<?php

namespace Reservation\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\View\Model\JsonModel;

use Reservation\Form\MailForm;

use Reservation\Model\Tables;

use Reservation\Model\Logs;

use Application\Model\Pays;

use Reservation\Model\Locataires;

use Reservation\Model\Resa;

use Reservation\Model\Listes;

use Reservation\Model\Modelesmail;

use Reservation\Model\Modelescampagne;

use Reservation\Form\LocataireForm;
use Reservation\Form\ResaForm;

use Reservation\Model\ProgrammeTable;

use Reservation\Model\Typelogement;

use Reservation\Model\Choix;

use Application\Model\Pile;

use Etudiant\Model\Comptes;

use Reservation\Model\Historiquemail;

use Reservation\Model\Document;

use Reservation\Model\Logement;

use Reservation\Model\Champdynamique;
use Reservation\Model\Valeurschampdynamique;

use Reservation\Model\Champs;


use Reservation\Tools\Mytcpdf;
use Reservation\Tools\Tools;
use Reservation\Tools\Unoconv;
use Reservation\Tools\Odtphp\library\odf;

use Reservation\Model\Etatintercontratconfig;
use Reservation\Model\Etatintercontrat;

use Reservation\Model\Batiment;

use Reservation\Model\Formulaire;
use Reservation\Model\Traduction;
use Reservation\Model\Residences;
use Reservation\Model\Configuration;

use Reservation\Model\LocatairesAccesResa;
use Reservation\Form\LocataireARForm;

use Reservation\Model\Apisignature;
use Reservation\Model\ApisignatureTable;
use Reservation\Model\Apisettingsignature;
use Reservation\Model\ApisettingsignatureTable;
use Reservation\Model\Apipms;
use Reservation\Model\ApipmsTable;
use Reservation\Model\Apisig;
use Reservation\Model\ApisigTable;

use DOMPDFModule\View\Model\PdfModel;

use Zend\Form\Form;

use Application\Model\PmsGen;
use Application\Model\Pms;
use Application\Model\CeriFoyer;
use Application\Model\BredeaSql;
use Application\Model\UrlToken;

use Application\Model\SignatureGen;
use Application\Model\Signature;

use Application\Model\SigGen;
use Application\Model\Sig;

use Zend\Session\Container;
use Zend\Db\Sql\Predicate;

use Reservation\Model\Demandes;

use Reservation\Model\User;
use Reservation\Model\Colis;
use Reservation\Model\Typemail;

use Reservation\Model\IntercontratTable;
use Reservation\Model\HistoriqueSMS;
use Zend\Db\Sql\Sql;

use Zend\Authentication\Adapter\AdapterInterface;

use Reservation\Helper\GlobalHelper;

use Reservation\Model\ChampsCatsTable;
use Reservation\Model\FiltresTable;

use Reservation\Model\Campagne;

use Reservation\Model\PLAITable;

use Reservation\Model\PrestaTable;

use Reservation\Model\ChargesTable;

use Reservation\Model\HistoriqueMailUsersTable;

use Reservation\Model\DomiciliationsTable;

use Reservation\Model\ConfigParcousTable;
use Zend\Db\Sql\Expression;

use Reservation\Model\FactureTable;
use Reservation\Model\ConfigMailsTable;

use Reservation\Model\CatalogueTable;

use Reservation\Model\ConfigFiltersTable;
use Reservation\Model\MultisuivisTable;
use Reservation\Model\Dashboard;
use Reservation\Model\OngletsFormulairesTable;
use Reservation\Model\CategorieDocumentFormulaireTable;
use Reservation\Model\TypeSuivisFormulaireTable;
use Reservation\Model\FormuleExcelTable;
use Reservation\Model\CategorieDocumentTable;
use Reservation\Model\FinancierTable;
use Reservation\Model\Code;
use Reservation\Model\PrestationsCheckinTable;
use Reservation\Model\ChampsCafTable;
use Reservation\Model\ModelesMailConditionsTable;
use Reservation\Model\SEPATable;
use Reservation\Model\FormulairesLogeTable;

use Zend\Http\Client;
use Zend\Http\Request;
use Zend\Stdlib\Parameters;

class ListeController extends AbstractActionController
{
	protected $locatairesTable;
	protected $logsTable;
	protected $reservationTable;
	protected $listesTable;
	protected $modelesmailTable;
	protected $paysTable;
	protected $programmeTable;
	protected $typelogementTable;
	protected $pileTable;
	protected $compteTable;
	protected $historiquemailTable;
	protected $historiquePushTable;
	protected $modelesPushTable;
	protected $documentTable;
	protected $logementTable;
	protected $champdynamiqueTable;
	protected $valeurschampdynamiqueTable;
	protected $choixTable;
	protected $champsTable;
	protected $etatICConfigTable;
	protected $batimentTable;
	protected $modelescampagneTable;

	protected $formulaireTableModel;
	protected $traductionTable;
	protected $residencesTable;
	protected $configurationTable;
	protected $locatairesAccesResaTable;
	protected $actionsjsTable;
	protected $champsFormTable;

	protected $edlModeleTable;
	protected $edlTable;
	protected $edlCatTable;
	protected $edlSousCatTable;
	protected $edlArticleTable;
	protected $edlParametresTable;

	protected $demandesTable;
	protected $demandesModelesTable;

	protected $etatICTable;

	protected $userTable;
	protected $colisTable;
	protected $typemailTable;

	## Mémorisation du descripteur de PMS et de SIG
	## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	protected $pms;
	protected $sig;
	protected $historiqueSMSTable;
	protected $campagneTable;
	protected $pmsGen;

	protected $cafTable;
	protected $cafDemandeIdealTable;

	protected $prestaTable;
	protected $chargesTable;
	protected $globalHelper;
	protected $HistoriqueMailUsersTable;
	protected $domiciliationsTable;

	protected $configParcousTable;
	protected $factureTable;
	protected $prestationTable;
	protected $configMailsTable;

	protected $catalogueTable;

	protected $configFiltersTable;
	protected $SuivisTable;
	protected $dashboardTable;
	protected $ongletsFormulairesTable;
	protected $categorieDocumentFormulaireTable;
	protected $typeSuivisFormulaireTable;
	protected $formuleExcelTable;
	protected $categorieDocumentTable;
	protected $financierTable;
	protected $codeTable;
	protected $prestationsCheckin;
	protected $champsCafTable;
	protected $modelesMailConditionsTable;
	protected $sepaTable;
	protected $formulairesLogeTable;

	## variabale pour sauvgarder les different messages de retours des actions sous forme de tableau $t['action'][typeMessage] = msg;
	private $messages = array();

	public function onDispatch(\Zend\Mvc\MvcEvent $e)
	{
		$mesParams	= $this->getEvent()->getRouteMatch()->getParam('mesParams');
		$passer = false;
		if(is_array($mesParams) && !empty($mesParams['from']) && $mesParams['from'] == 'application') {
			$passer = true;
		}
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		if (!$auth->hasIdentity() && !$passer) {
			return $this->redirect()->toRoute('zfcuser/login');
		}
		return parent::onDispatch($e);
	}
	protected $apisignatureTable;
	protected $apisettingsignatureTable;
	protected $documentLocataireTable;

	public function indexAction()
	{

		// $conf = $this->getConfigurationTable()->getConfig(1);
		// $this->initPMS(1, 58);

		// if ($this->pms) {

		// 	$className = $this->pms->getClassName();
		// 	if ($className === "Bredea") {
		// 		$bredea	= $this->pms;
		// 		// check if we have a prestation which doesn't exist on bredea database
		// 		// $prestationsBredea = $bredea->getRows('001fprest');
		// 	} elseif ($className === "CeriFoyer") {
		// 		## ne rien faire
		// 	}
		// }

		// $resaPMS	= $this->pms->getDemandePMS(568);
		// // $soldes = $this->pms->printCompteResaPMS(568, true);
		// echo "<pre>";
		// print_r($resaPMS);
		// echo "</pre>";
		// die();

		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		## mes lien vers une liste précise
		$modeListeFromUrl = $this->params()->fromRoute('mode', '');
		$idListeFromUrl = $this->params()->fromRoute('id', '');
		$idModeListeFromUrl = '';
		if ($modeListeFromUrl != '') {
			$globalHelper = new GlobalHelper($this->getServiceLocator());
			//on recup l'id du mode choisi
			$modesCleUrl = $globalHelper->getModesCleUrl();
			$idModeListeFromUrl = array_search($modeListeFromUrl, $modesCleUrl);
			if ($modeListeFromUrl == "factures") {
				$idListeFromUrl = $globalHelper->getIdCssTypeListeFactures($idListeFromUrl);
			}
		}


		$sessSerrures = new Container('serrures');
		$sessSerrures->numeroEncodeur = '1';

		$sessListe = new Container('liste');
		$sessListe->rows = null;// vider le resultat de la requete getLsite()

		///$form = new MailForm();
		$session = new Container('mailing');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}



		## Update idCampagne des nouvelle resa : 20-10-2015
		//$timestart = microtime(true);
		/*$tableObj = new Tables('reservations',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select = $tableObj->getTable()->getSql()->select();
		$select->where->isNull('idCampagne');
		$rows = $tableObj->getTable()->selectWith($select);

		foreach ($rows as $row){

			$idCampage = $this->getCampagneDeResa($row);
			if($idCampage){
				$tableObj->getTable()->update(array('idCampagne'=>$idCampage),array('id'=>$row->id));
			}
		}*/

		/*$timeend = microtime(true);
		$execution_time = $timeend - $timestart;
		$page_load_time = number_format($execution_time, 3);
		echo "<br>Fonction <b>\"UP Campage()\"</b> execute en <b style=\"color:red\">" . $page_load_time . "</b> sec";
		*/
		## Fin update

		## MAJ des choix de type de logement, apres la nouvelle methode
		//$timestart = microtime(true);
		/*$resas = $this->getTableObjet('reservations')->select();
		foreach ($resas as $row) {
			$choix = $this->getTableObjet('choix_typelogement')->select(array('idReservation'=>$row->id))->current();
			if(!$choix){
				if($row->idTypeLogement1){
					$choix = array('numeroChoix'=>'1','idTypeLogement'=>$row->idTypeLogement1,'idReservation'=>$row->id);
					$this->getTableObjet('choix_typelogement')->insert($choix);
				}
				if($row->idTypeLogement2){
					$choix = array('numeroChoix'=>'2','idTypeLogement'=>$row->idTypeLogement2,'idReservation'=>$row->id);
					$this->getTableObjet('choix_typelogement')->insert($choix);
				}
				if($row->idTypeLogement3){
					$choix = array('numeroChoix'=>'3','idTypeLogement'=>$row->idTypeLogement3,'idReservation'=>$row->id);
					$this->getTableObjet('choix_typelogement')->insert($choix);
				}
			}
		}*/
		/*$timeend = microtime(true);
		$execution_time = $timeend - $timestart;
		$page_load_time = number_format($execution_time, 3);
		echo "<br>Fonction <b>\"UP Choix de logement()\"</b> execute en <b style=\"color:red\">" . $page_load_time . "</b> sec";
		*/

		//pour desactiver les bouton en cas le droit est R
		$authorize = $this->getServiceLocator()->get('BjyAuthorize\Provider\Identity\ProviderInterface');
		$roles = $authorize->getIdentityRoles();
		$roleId = !empty($roles) ? $roles[0] : '';
		$hide = "";

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : gestId=$gestId roleId=$roleId modeListeFromUrl=$modeListeFromUrl idListeFromUrl=$idListeFromUrl");

		if (!$roleId) {
			return $this->redirect()->toRoute('zfcuser/login');
		} else {
			$tableObj = new Tables('modules_role', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$result = $tableObj->getTable()->select(array('idModule' => 4, 'idRole' => $roleId))->current();
			if ($result) {
				if ($result->droit == "R") {
					$hide = "hide";
				}
			}
		}

		if (1) {
			## Lecture des descriptions des champs des listes
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonResaDatatableState = $request->getPost('jsonResaDatatableState', array());
			$jsonResaDatatableFrom  = 'POST';

			$idListe = 0; // Wadie ERREUR : Je déclare la variable pour éviter les erreurs puis j'ajoute aussi une condition if $idListe.
			$typeListe = 0; // Wadie Erreur : De même pour $typeListe

			if (empty($jsonResaDatatableState) && $idListe) {
				// Wadie Erreur : $idListe n'est pas déclarée avant..
				$jsonResaDatatableState = $this->loadResaState($idListe);
				$jsonResaDatatableFrom  = 'BDD';
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe jsonResaDatatableState($jsonResaDatatableFrom)=".json_encode($jsonResaDatatableState));
			$jsonResaDatatableFilter        = array_key_exists('filter', $jsonResaDatatableState) ? $jsonResaDatatableState['filter'] : [];

			## Valeurs uniques pour les différents selects
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$selectOptions	= array();

			## Constitution d'une liste des lignes
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$rowsAll	= array();

			if ($jsonResaDatatableFilter) {
				## Initialisation de la liste des champs de la liste des réservations
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getResaFields($idListe, $jsonResaDatatableFilter);
			}
		}
		/*
		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$select1 = $tableObj->getTable()->getSql()->select();
		$select1->where(array('idTheme' => '1'));
		$select1->order(array('ordre ASC'));
		$theme1Result = $tableObj->getTable()->selectWith($select1);

		$select2 = $tableObj->getTable()->getSql()->select();
		$select2->where(array('idTheme' => '2'));
		$select2->order(array('ordre ASC'));
		$theme2Result = $tableObj->getTable()->selectWith($select2);

		$select3 = $tableObj->getTable()->getSql()->select();
		$select3->where(array('idTheme' => '3'));
		$select3->order(array('ordre ASC'));
		$theme3Result = $tableObj->getTable()->selectWith($select3);

		$select6 = $tableObj->getTable()->getSql()->select();
		$select6->where(array('idTheme' => '6'));
		$select6->order(array('ordre ASC'));
		$theme6Result = $tableObj->getTable()->selectWith($select6);


		//$theme1 = $tableObj->getTable()->select(array('idTheme' => '1'));
		//$theme2 = $tableObj->getTable()->select(array('idTheme' => '2'));
		//$theme3 = $tableObj->getTable()->select(array('idTheme' => '3'));

		$theme1 = array();
		$theme2 = array();
		$theme3 = array();
		$theme6 = array();
		$tailleTotal = 0;

		foreach ($theme1Result as $t1) {
			$t1->checked = null;
			$theme1[] = $t1;
			$tailleTotal += $t1->taille;
		}

		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		foreach ($champsDynamiques as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->checked = null;
			$theme1[$obj->code] = $obj;
		}

		$added = false;
		foreach ($theme2Result as $t2) {
			$t2->checked = null;
			$theme2[] = $t2;
			if (!$added) {
				if ($t2->code == 'loyer3') {
					$maxChoixTypeLogement = $this->getMaxChoix();
					if ($maxChoixTypeLogement > 3) {
						for ($i=4; $i <=$maxChoixTypeLogement  ; $i++) {
							$tCopy = clone($t2);
							$tCopy->code = 'typeLogement'.$i;
							$tCopy->nom = 'Type logement choix '.$i;

							$exist = $this->getTableObjet('champs')->select(array('code'=>$tCopy->code))->current();
							if (!$exist) {
								$tData = array('code'=>$tCopy->code,
											'nom'=>$tCopy->nom,
											'idTheme'=>2,
											'ordre'=>$tCopy->ordre,
											'taille'=>$tCopy->taille
											);
								$this->getTableObjet('champs')->insert($tData);
								$theme2[] = $tCopy;
							}


							$tCopy = clone($t2);
							$tCopy->code = 'loyer'.$i;
							$tCopy->nom = 'Choix '.$i.' loyer';

							$exist = $this->getTableObjet('champs')->select(array('code'=>$tCopy->code))->current();
							if (!$exist) {
								$tData = array('code'=>$tCopy->code,
											'nom'=>$tCopy->nom,
											'idTheme'=>2,
											'ordre'=>$tCopy->ordre,
											'taille'=>$tCopy->taille
											);
								$this->getTableObjet('champs')->insert($tData);
								$theme2[] = $tCopy;
							}
						}
						$added = true;
					}
				}
			}

			$tailleTotal += $t2->taille;
		}

		foreach ($theme3Result as $t3) {
			$t3->checked = null;
			$theme3[] = $t3;
			$tailleTotal += $t3->taille;
		}

		foreach ($theme6Result as $t6) {
			$t6->checked = null;
			$theme6[] = $t6;
			$tailleTotal += $t6->taille;
		}
		*/

		//etats de liste public,private
		$tableObj2 = new Tables('etat_liste', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$etats = $tableObj2->getTable()->select();

		if ($request->isPost()) {
			//on récupère la liste choisi
			$session->liste = $request->getPost('locataire');
		}

		//$rows = $this->getLocatairesTable()->getListe();
		//$rows = $this->getResaTable()->getListe();
		/*foreach ($rows as $row){
			var_dump($row);
			}
			exit();*/
		$rows = array();

		//$allThemes = array_merge($theme1, $theme2, $theme3, $theme6);

		## Extraire la liste des listes permises : celles du profil et les privées
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$allowedListe = $this->getAllowedListes();

		## Extraire la liste des profils effectivement créés pour les utilisateurs
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$allProfiles	= $this->getTableObjet('user_role')->select();
		$allowedProfiles = array();
		if ($allProfiles) {
			foreach ($allProfiles as $row) {
				if ($row->role_id != 'guest' && $row->role_id != 'user') {
					$allowedProfiles[]	= $row;
				}
			}
		}

		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		//mailing
		//etats de liste public,private
		/**$tableObj3 = new Tables('type_email', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$types = $tableObj3->getTable()->select(array('auto'=>'1'));
		$typesOption = array();
		foreach ($types as $t) {
			$typesOption[$t->id] = $t->type;
		}

		$form->get('idType')->setAttribute('options', $typesOption);


		$modeles = $this->getModelesmailTable()->fetchAll($idProfile);
		$modelesOption = array();
		foreach ($modeles as $m) {
			//on affiche les listes public
			if ($m->idType != '2') {
				$modelesOption[$m->id] = $m->nomModele;
			} elseif ($m->idUser == $gestId) {
				$modelesOption[$m->id] = $m->nomModele;
			}
		}

		$form->get('idModele')->setAttribute('options', $modelesOption);
		**/

		##Types de liste: exp demande
		$typesListeRes = $this->getTableObjet('type_liste')->select();
		$typesListe = array();
		foreach ($typesListeRes as $row) {
			$typesListe[$row->id] = $row;
		}

		## Filtre bandeau
		$sessFB = new Container('filtreBandeau');
		$sessFiltresValeurs = isset($sessFB->filtres) ? $sessFB->filtres : array();

		$filtresBandeau = $filtreValeurs = array();
		if ($this->getFiltresTable()->isModeFiltreActive()) {
			$filtresBandeau = $this->getFiltresTable()->getFiltresActive();
			foreach ($filtresBandeau as $f) {
				if ($f->equivalentSql == 'idResidence') {
					$residences =  $this->getResidencesTable()->fetchByGest($gestId);
					$options = array();
					foreach ($residences as $r) {
						$options[$r->id] = $r->nom;
					}
					$filtreValeurs[$f->equivalentSql] = $options;
					//chargement des batiment si on a la residence dans la session
					if (!empty($sessFiltresValeurs[$f->equivalentSql])) {
						$bats = $this->getBatimentTable()->getBatimentsDeResidence($sessFiltresValeurs[$f->equivalentSql]);
						$batOptions = array();
						foreach ($bats as $r) {
							$batOptions[$r->id] = $r->nom;
						}
						$filtreValeurs['idBatiment'] = $batOptions;
					}
				} elseif ($f->equivalentSql == 'idCampagne') {
					$campagnes = $this->getCampagneTable()->fetchAll();
					$options = array();
					foreach ($campagnes as $r) {
						$options[$r->id] = $r->nom;
					}
					$filtreValeurs[$f->equivalentSql] = $options;
				} elseif ($f->equivalentSql == 'idProgramme') {
					$progs = $this->getProgrammeTable()->getProgrammesParent();
					$options = array();
					foreach ($progs as $p) {
						$options[$p->id] = $p->nom;
					}
					$filtreValeurs[$f->equivalentSql] = $options;
					//chargement des SP si on a le prog dans la session
					if (!empty($sessFiltresValeurs[$f->equivalentSql])) {
						$sProgs = $this->getProgrammeTable()->getSousProgrammes($sessFiltresValeurs[$f->equivalentSql]);
						$spOptions = array();
						foreach ($sProgs as $r) {
							$spOptions[$r->id] = $r->nom;
						}
						$filtreValeurs['idSousProgramme'] = $spOptions;
					}
				} elseif ($f->equivalentSql == 'idBatiment' && !array_key_exists('idResidence', $filtreValeurs)) {
					//si on active que le filtre batiment et pas celui de residence
					$bRows =  $this->getBatimentTable()->fetchByGest($gestId);
					$options = array();
					foreach ($bRows as $r) {
						$options[$r->id] = $r->nom;
					}
					$filtreValeurs[$f->equivalentSql] = $options;
				} elseif ($f->equivalentSql == 'idSousProgramme' && !array_key_exists('idProgramme', $filtreValeurs)) {
					//si on active que le filtre batiment et pas celui de residence
					$spRows =  $this->getProgrammeTable()->getAllSousProgrammes();
					$options = array();
					foreach ($spRows as $r) {
						$options[$r->id] = $r->nom;
					}
					$filtreValeurs[$f->equivalentSql] = $options;
				}
			}
			if (!empty($sessFiltresValeurs)) {
				//on supprime de la session les filtres non active
				$filtresNA = $this->getFiltresTable()->getFiltresNonActive();
				foreach ($filtresNA as $f) {
					if (!empty($sessFiltresValeurs[$f->equivalentSql])) {
						unset($sessFiltresValeurs[$f->equivalentSql]);
					}
					if (!empty($sessFB->filtres[$f->equivalentSql])) {
						unset($sessFB->filtres[$f->equivalentSql]);
					}
				}
			}
		} else {
			$sessFiltresValeurs = array();
			$sessFB->filtres = null;
		}

		$globalHelper = new GlobalHelper($this->getServiceLocator());
		$menu = $globalHelper->getMenuModeListe();

		// Récupération du menu par défaut par profile
		// var_dump($gestId);die();
		$user_role_linker = $this->getTableObjet('user_role_linker')->select(array('user_id' => (int) $gestId))->current();
		// var_dump($user_role_linker);die();

		$droit = $this->getDroitTable()->getRole($user_role_linker->role_id);
		// var_dump($droit->role_id);die();

		// droit pour la liste par défaut
		$parentN = $this->getTableObjet('droit_elements')
		->select(array('unique_name' => 'liste-input-mode-liste'))
		->current();
		$droitElements = $this->getTableObjet('droit_elements')
		->select(array('parent_id' => $parentN->id))->toArray();

		foreach ($droitElements as $key => $de) {
			$droit_configs_res = $this->getTableObjet('droit_config')
			->select(array('droit_id' => $de['id'], 'role_id' => $idProfile, 'default_list' => 1))
			->current();

			if ($droit_configs_res) {
				$droit_config = $droit_configs_res;
				break;
			}
		}

		if ($idModeListeFromUrl) {
			$menuParDefaut = $this->getTableObjet('droit_elements')
			->select(array('id_attr' => $idModeListeFromUrl))->current();
		} else {
			//$droit_config = $this->getTableObjet('droit_config')
			// ->select(array('role_id' => (string) $droit->role_id, 'default_list' => 1))->current();
			// var_dump($droit_config);die();

			$menuParDefaut = $this->getTableObjet('droit_elements')
			->select(array('id' => (int) $droit_config->droit_id))->current();
		}

		// var_dump($menu);
		// die();

		// SI on a pas de menu par défaut ou le droit n'est pas bon  alors on selectionne le premier
		if (!$menuParDefaut || ($menuParDefaut && $_SESSION['USERDROIT'][$menuParDefaut->unique_name] == 'X')) {
			$menuParDefaut = $menu[0];
		} else {
			$menuParDefaut['cleMode'] = $globalHelper->getModeDefaultCle($menuParDefaut['id_attr']);
		}

		if (!$idModeListeFromUrl) {
			//on cherche la liste par defaut si existe
			$idDroit = $menuParDefaut->id;
			if ($idDroit) {
				$listeParDefaut = $this->getTableObjet('listes_par_defaut')->select(array('idDroit' => $idDroit, 'idProfile' => $idProfile))->current();
				if ($listeParDefaut) {
					$modesCleUrl = $globalHelper->getModesCleUrl();
					$idListeFromUrl = $listeParDefaut->idListe;
					$idAttrDroit = '';
					if ($menuParDefaut->id_attr) {
						$idAttrDroit = $menuParDefaut->id_attr;
					} elseif (substr($menuParDefaut->unique_name, 0, 22) == 'mode-input-typesuivis-') {
						$idAttrDroit = str_replace('mode-input-typesuivis-', 'typeSuivis-', $menuParDefaut->unique_name);
					}
					if ($idAttrDroit) {
						$idModeListeFromUrl = $idAttrDroit;
						$modeListeFromUrl = $modesCleUrl[$idModeListeFromUrl];
					}
				}
			}
		}

		if ($menuParDefaut && !$menuParDefaut->id_attr) {
			if (substr($menuParDefaut->unique_name, 0, 22) == 'mode-input-typesuivis-') {
				$menuParDefaut->id_attr = $menuParDefaut['id_attr'] = str_replace('mode-input-typesuivis-', 'typeSuivis-', $menuParDefaut->unique_name);
			}
		}

		// var_dump($menuParDefaut);die();
		// echo "<pre>";
		// var_dump($menuParDefaut);
		// echo "</pre>";
		// die();

		// Mode d'impression carte usager
		$conf = $this->getTableObjet('configuration')->select(array('id' => 1))->current();
		$modePrint = $conf->modeImpressionCartes;

		## ouverture de la fiche usager depuis la page valider(portail demande)
		$cible = isset($_GET['cible']) ? trim($_GET['cible']) : '';
		$ouvrirFicheUsager = false;
		if($cible == 'fu' && (($_SESSION['USERDROIT']['ficheclient'] == 'W' || $_SESSION['USERDROIT']['ficheclient'] == 'R'))) {
			$session = new Container('reservation');
			$resa = $session->reservation;
			$idResa	= $resa ? $resa->id : 0;
			$idDp = $session->idDp ? $session->idDp : null;
			if($idResa || $idDp) {
				$ouvrirFicheUsager = true;
			}
		}

		return array(
					//'form' => $form,
					//'reservations' => $this->getResaTable()->fetchAll(),
					'rows' => $rows,
					//'theme1' => $theme1,
					//'theme2' => $theme2,
					//'theme3' => $theme3,
					//'theme6' => $theme6,
					//'allThemes' => $allThemes,
					//'tailleTotal' => $tailleTotal,
					'etats' => $etats,
					'listes' => $allowedListe,
					'hide' => $hide,
					'typesListe' => $typesListe,
					'categoriesListes' => $this->getListesTable()->getCategoriesListe($adapter),
					'modalFicheClient' => $this->getFicheClienModal(),
					'profiles' => $allowedProfiles,
					'idProfile' => $idProfile,
					'typesSuivis' => $this->getListeTypesSuivis(),
					'modeListeFromUrl' => $modeListeFromUrl,
					'idListeFromUrl' => $idListeFromUrl,
					'idModeListeFromUrl' => $idModeListeFromUrl,
					'champModalHtml' => $this->loadChampsModal(),
					'filtresBandeau' => $filtresBandeau,
					'filtreValeurs' => $filtreValeurs,
					'sessFiltresValeurs' => $sessFiltresValeurs,
					'menu' => $menu,
					'menuParDefaut' => $menuParDefaut,
					'typesCatalogue' => $this->getCatalogueTable()->getTypesCatalogueListe(),
					'modePrint' => $modePrint,
					'conf' => $conf,
					'campagnes' => $this->getCampagneTable()->fetchByGest($gestId),
					'ouvrirFicheUsager' => $ouvrirFicheUsager,
					'idResa' => $idResa,
					'idDp' => $idDp,
		);
	}



	public function droitListeAction()
	{
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$idListe = $request->getPost('idListe');
			$menuListeId = $this->getTableObjet('droit_elements')->select(array('id' => $idListe))->current();
			return new JsonModel(array('data' => $menuListeId));
		}
	}

	public function corrigerTableICAction()
	{
		$i = 0;
		$resas = $this->getTableObjet('reservations')->select(array('archive' => '0', 'etat' => 6));
		foreach ($resas as $resa) {
			$icDeResa = $this->getTableObjet('intercontrat')->select(array('idReservation' => $resa->id));
			foreach ($icDeResa as $ic) {
				if (!$resa->idIntercontrat || $ic->idEtat != $resa->idIntercontrat) {
					$this->getTableObjet('intercontrat')->update(array('valide' => '1'), array('id' => $ic->id));
					$i++;
				}
			}
			if ($resa->idIntercontrat == 5) {
				$this->getTableObjet('reservations')->update(array('idIntercontrat' => null), array('id' => $resa->id));
			}
		}
		echo "$i lignes maj";
		exit();
	}

	public function corrigerDecalageICAction()
	{
		$i = 0;
		$resas = $this->getTableObjet('reservations')->select(array('archive' => '0', 'etat' => 6));
		//on remis l idIntercontrat à la derniere etat dans la table intercontrat
		foreach ($resas as $resa) {
			if ($resa->idIntercontrat) {
				$ICEnCours = $this->getTableObjet('intercontrat')->select(array('idReservation' => $resa->id, 'idEtat' => $resa->idIntercontrat))->current();
				if (!$ICEnCours) {
					$etatOldResult = $this->getTableObjet('intercontrat')->select(array('idReservation' => $resa->id));
					foreach ($etatOldResult as $et) {
						$etatOld = $et;
					}
					//on maj idIntercontrat avec le dernier etat trouvé dans la table intercontrat

					$this->getTableObjet('reservations')->update(array('idIntercontrat' => $etatOld->idEtat), array('id' => $resa->id));

					//echo $resa->id." idEtat new : ".$etatOld->idEtat." old : ".$resa->idIntercontrat."<br>";
					$i++;
					//exit();
				}
			}
		}
		echo "$i lignes maj";
		exit();
	}

	## script de correction des durée IC
	public function corrigerDureeICAction()
	{
		$resas = $this->getTableObjet('reservations')->select(array('archive' => '0', 'etat' => 6));
		$tableIC = $this->getTableObjet('intercontrat');
		$etatsIC = $this->getAllEtatIC();
		$listeIC = array();
		foreach ($etatsIC as $ic) {
			$listeIC[$ic->id] = $ic;
		}
		$k = 0;
		foreach ($resas as $resa) {
			if (1) {
				$ICDeResa = array();
				$i = 0;
				//on remplis la liste $ICDeResa pour s en servir juste après, pour récup les etat suivante
				/*foreach($listeIC as $idEtat=>$etat){
					$ICRow = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id,'idEtat'=>$idEtat))->current();
					if($ICRow){
						$ICDeResa[$i] = $ICRow;
						$i++;
					}
				}*/
				//$ICRows =  $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id));

				$select = $tableIC->getSql()->select();
				$select->where(array('idReservation' => $resa->id));
				//$select->order(array('dateEtat ASC'));
				$ICRows = $tableIC->selectWith($select);
				foreach ($ICRows as $ICRow) {
					$ICDeResa[$i] = $ICRow;
					$i++;
				}
				$j = 0;

				foreach ($ICDeResa as $index => $ICRow) {
					//$ICRow = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id,'idEtat'=>$idEtat,'valide'=>'1'))->current();
					if ($ICRow && !empty($ICDeResa[$j + 1]) && $ICRow->dateEtat) {
						$dateEtat = new \DateTime($ICRow->dateEtat);
						$dateNext = new \DateTime($ICDeResa[$j + 1]->dateEtat);
						$difference = $dateEtat->diff($dateNext);
						$duree = $difference->format('%a');
						//on calcule le retard
						$etat = $listeIC[$ICRow->idEtat];
						$configDuree = $etat->duree;
						$decalage = $configDuree - $duree;
						//echo $ICRow->id." dateEtat : ".$ICRow->dateEtat." dateNext : ".$ICDeResa[$j+1]->dateEtat." duree = $duree<br>";

						//maj de la duree et/ou decalage
						if ($duree != $ICRow->duree) {
							$this->getTableObjet('intercontrat')->update(array('duree' => $duree), array('id' => $ICRow->id));
							echo "Duree : Resa ".$resa->id." etatID = ".$ICRow->idEtat." , duree : $duree , decalage $decalage dateEtat ".$ICRow->dateEtat." NEXT ".$ICDeResa[$j + 1]->dateEtat."<br>";
							$k++;
						}
						if ($decalage != $ICRow->decalage) {
							$this->getTableObjet('intercontrat')->update(array('decalage' => $decalage), array('id' => $ICRow->id));
							echo "Decalage : Resa ".$resa->id." etatID = ".$ICRow->idEtat." , duree : $duree , decalage $decalage dateEtat ".$ICRow->dateEtat." <br>";
						}
						$j++;
					}
				}

				// correction etat logement si la resa est en IC, idEtat = 3
				//if($resa->idIntercontrat) $this->getTableObjet('logements')->update(array('idEtat'=>3),array('id'=>$resa->idLogement));
			}
		}
		echo "Termine $k lignes maj";
		exit();
	}

	/*public function corrigerDecalageICOLDAction(){
		$i = 0;
		$resas = $this->getTableObjet('reservations')->select(array('archive'=>'0','etat'=>6));
		$premierEtat = $this->getPremierEtatIC();
		foreach($resas as $resa){
			if($resa->idIntercontrat){
				$ICEnCours = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id,'idEtat'=>$resa->idIntercontrat))->current();
				if(!$ICEnCours){
					//on save les etat avant dans une var
					$etatOldResult = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id));
					$etatOld = array();

					foreach($etatOldResult as $et){
						$etatOld[] = $et;
					}

					//on corrige les infos du premier etat
					$datePrev = new \DateTime($resa->dateDepart);
					$dateActuel = new \DateTime($etatOld[0]->dateEtat);
					$difference = $datePrev->diff($dateActuel);
					$duree = $difference->format('%a');



					//on calcule le retard
					$configDuree = $this->getDuree($resa->id, $premierEtat->id);
					echo $configDuree;exit();
					$decalage = $configDuree - $duree;

					$resaEtat = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$resa->id));
					$j=0;
					foreach($resaEtat as $er){

						if($j==0){
							$data = array();
							$data['duree'] = $duree;
							$data['decalage'] = $decalage;
							$data['dateEtat'] = $resa->dateDepart;
							##$this->getTableObjet('intercontrat')->update($data,array('id'=>$er->id));
							echo "Premiere ligne<br>";
							print_r($data);echo "<br><br>";
						}else{
							$data = array(
								'idReservation'=>$etatOld[$j-1]->idReservation,
								'duree'=>$etatOld[$j-1]->duree,
								'decalage'=>$etatOld[$j-1]->decalage,
								'valide'=>$etatOld[$j-1]->valide,
								'dateEtat'=>$etatOld[$j-1]->dateEtat,
								'commentaire'=>$etatOld[$j-1]->commentaire,
								'creation_date'=>$etatOld[$j-1]->creation_date,
								'userid'=>$etatOld[$j-1]->userid,
								);
							echo "autres ligne<br>";
							print_r($data);echo "<br><br>";
							##$this->getTableObjet('intercontrat')->update($data,array('id'=>$er->id));
						}
						$j++;
						if($j==sizeof($etatOld)){
							## on ajoute une ligne en dernier
							$data = array(
								'idEtat'=>$resa->idIntercontrat,
								'idReservation'=>$etatOld[$j-1]->idReservation,
								'duree'=>$etatOld[$j-1]->duree,
								'decalage'=>$etatOld[$j-1]->decalage,
								'valide'=>$etatOld[$j-1]->valide,
								'dateEtat'=>$etatOld[$j-1]->dateEtat,
								'commentaire'=>$etatOld[$j-1]->commentaire,
								'creation_date'=>$etatOld[$j-1]->creation_date,
								'userid'=>$etatOld[$j-1]->userid,
								);
							echo "Derniere ligne<br>";
							print_r($data);echo "<br><br>";
							##$this->getTableObjet('intercontrat')->insert($data);
						}
					}



					echo $resa->id."<br>";
					$i++;
					exit();
				}
			}

		}
		echo "$i lignes maj";
		exit();
	}*/

	public function importdemandeAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");
		//print_r($this->ajouterDemandeBredea(2384));
		echo "<br>Terminer";
		exit();
	}

	public function ajouterDemandeBredea($idResa, $codeSiteNew = '')
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

		if (!$idResa) {
			return false;
		}

		$numDemdande = "";
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$resa =  $this->getResaTable()->getResaWithPms($idResa);

				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);

					if ($this->pmsGen->site) {
						$bredea->site = $this->pmsGen->site;
					}

					$idLocataire = $resa->idLocataire;

					$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $idResa);
					//$resa = $this->getResaTable()->getResa($idResa);
					## choix de type de logement/residence
					$listeChoix = array();
					for ($i = 1; $i <= 3; $i++) {
						$choix = $this->getChoixTable()->getChoixByResaNumero($idResa, $i);
						$c = array();
						if ($choix) {
							$c['idPMS'] = $choix->idPMSDemande;//idPMSDemande
							if ($choix->idResidence) {
								$residence = $this->getResidencesTable()->getResidence($choix->idResidence);
								if ($residence) {
									$c['residence'] = $residence->idPMS;
								}
							}
							$listeChoix[$i] = $c;
						}
					}

					if ($resa->idProgramme) {
						$r = $this->getTable("programme_campagne")->select(array('idProgramme' => $resa->idProgramme, 'idCampagne' => $resa->idCampagne))->current();
						if ($r) {
							$site = $this->getResidencesTable()->getResidence($r->idResidence);
							$typre = $r->typre ? $r->typre : "";
							$codeSite = $site ? $site->idPMS : '';
							if ($codeSite) {
								$bredea->site = $codeSite;
							}
							if ($typre) {
								$bredea->typre = $typre;
							}
						}
					}

					//si on a le logement, on prend le site du logement
					if ($resa->idLogement > 0) {
						$siteDeLog = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						if ($siteDeLog && $siteDeLog->idPMSResidence) {
							$bredea->site = $siteDeLog->idPMSResidence;
						}
					}

					##fin choix de type de logement/residence

					##cas changement campagne
					if($codeSiteNew && trim($codeSiteNew) != '') {
						$bredea->site = $codeSiteNew;
					}

					//infos des select avec idPMS
					$infos = $this->getLocatairesTable()->getInfosSelect($idLocataire, $adapter, $idResa);
					$this->getResaTable()->updateResa(array('idApiPms' => $resa->idApiPms ?: 1, 'typre' => $bredea->typre ? $bredea->typre : '', 'codeSite' => $bredea->site ? $bredea->site : null, 'stateApiPms' => 'DemandeEnvoyee'), array('id' => $idResa));

					$numDemdande = $bredea->ajouterDemandeReservation($loc, $resa, $listeChoix, $infos);
					//if($numDemdande){ // }
					$this->getLocatairesTable()->updateLocataire($idLocataire, array('idPMS' => $numDemdande));
					$this->getResaTable()->updateResa(array('idPMS' => $numDemdande, 'stateApiPms' => 'DemandeEnvoyee'), array('id' => $idResa));
					$this->getResaTable()->updateDatesDemande($resa);

					$bredea->closeConnect();
					$this->pms	= null;
					$this->pmsGen	= null;
				}else{
					echo 'Aucun PMS init';
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $numDemdande;
	}

	//corriger les etat de logement par rapport au etat de resa
	public function corrigeretatlogementAction()
	{

		//on remis tout les logements occuper à dispo
		$this->getLogementTable()->updateLogement(array('idEtat' => 1), array('idEtat' => 4));

		$allresa = $this->getTableObjet('reservations')->select(array('archive' => '0'));
		$k = $j = 0;
		foreach ($allresa as $resa) {
			if ($resa->etat == 7) {
				if ($resa->idLogement) {
					$this->getTableObjet('logements')->update(array('idEtat' => 4), array('id' => $resa->idLogement));
					$j++;
				}
			}
			if ($resa->etat == 6) {
				if ($resa->idLogement) {
					//$this->getTableObjet('logements')->update(array('idEtat'=>1),array('id'=>$resa->idLogement));
					//$j++;
				}
			}
		}
		echo "$j lignes corriger<br>";
		exit();
	}

	public function testwlAction()
	{
		//print_r($this->getResaTable()->getListe(11901)->current());exit();

		$mails = $this->getTableObjet('historique_mail')->select();// >16
		$i = 0;
		foreach ($mails as $mail) {
			if ($mail->id > 16) {
				$loc = $this->getTableObjet('locataires')->select(array('id' => $mail->idLocataire))->current();
				$email = $loc->emailHec ? $loc->emailHec : $loc->email;
				//echo $loc->id." $email<br>";
				$resa = $this->getTableObjet('reservations')->select(array('idLocataire' => $loc->id, 'etat' => '7'))->current();
				if ($resa) {
					//$i++;
				} else {
					echo $loc->id." $email<br>";
					$i++;
				}
			}
		}
		echo "$i lignes";
		exit();

		//remettre les logement en dispo
		$i = 0;
		$allresa = $this->getResaTable()->fetchAll(6);
		foreach ($allresa as $resa) {
			if ($resa->idLogement) {
				//on check si il ya pas de resa accueilli avec le meme logement
				$r1 = $this->getTableObjet('reservations')->select(array('idLogement' => $resa->idLogement, 'etat' => '7'))->current();
				$r2 = $this->getTableObjet('reservations')->select(array('idLogement' => $resa->idLogement, 'etat' => '3'))->current();
				if (!$r1 && !$r2) {
					$this->getTableObjet('logements')->update(array('idEtat' => '1'), array('id' => $resa->idLogement));
					$i++;
				}
			}
		}
		echo "$i mis en dispo";
		exit();

		/*$resav1 = $this->getTableObjet('reservations_v1')->select();
		$i=0;//3652
		foreach($resav1 as $rv1){
			$resav2 = $this->getTableObjet('reservations')->select(array('id'=>$rv1->id))->current();
			if($resav2){
				if($resav2->etat != $rv1->etat){
					print_r($resav2);
					echo "<br><br>";
					print_r($rv1);
					echo "<br>****<br>";
					echo $rv1->id." etat v1 : ".$rv1->etat." etat v2 : ".$resav2->etat."<br>";
					exit();
				}

			}
		}
		echo "$i lignes";*/

		$allresa = $this->getResaTable()->fetchAll(2);
		$k = $j = 0;
		foreach ($allresa as $resa) {
			$dateArrrOK = strtotime($resa->dateArrivee) > strtotime(date('2010-01-01'));
			if ($dateArrrOK && (strtotime($resa->dateDemandeReservation) >= strtotime($dateDebut))) {
				//on verife si les frais sont paye
				$cautionPaye = $fddPaye = false;
				$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $resa->id));
				foreach ($comptes as $c) {
					//caution
					if ($c->type == 3 && $c->etat == 2 && $c->solde == 0) {
						$cautionPaye = true;
					}
					//caution
					if ($c->type == 4 && $c->etat == 2 && $c->solde == 0) {
						$fddPaye = true;
					}
					if ($cautionPaye && $fddPaye) {
						//on maj l etat de resa à 3
						$this->getResaTable()->updateResa(array('etat' => '3'), array('id' => $resa->id));
						echo "etat corriger ".$resa->id." <br>";
						$k++;
					}
				}
				$j++;
			}
		}
		echo "$k lignes corriger<br>";
		echo "$j option";

		exit();
	}

	public function testbredeaAction()
	{

		//print_r($this->getDernierEtatIC());
		exit();
		//$bredea = new BredeaSql();
		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');

		$resa = $this->getResaTable()->getResa(22);

		$return = $this->getReservationPms(22);
		//print_r($return);
		print_r($bredea->lireReservation('26', '00', 'demande'));
		exit();

		//echo ($this->ajouterDemandeBredea(11465));exit();

		$regls = $bredea->getReglementFacture(array('codeSite' => '02', 'numDossier' => '00728', 'noFacture' => 'P080128'));
		print_r($regls);
		exit();

		$where = array();
		//$where['hfa_site'] = '03';
		//$where['hfa_typre'] = 'R';
		//$where['hfa_dossier'] = '00425';
		$where['hfa_date'] = '20161122';

		$return = $bredea->getRows('001fhistofac', $where);

		$return = $bredea->getRows('sofsoc', array());
		print_r($return);
		exit();



		//$idResa = 11465;


		exit();
		//$return = $this->getReservationPms(9846);
		//$return = $bredea->lireReservation('00001','01','dossier');
		$return = $bredea->getRowTest('001fdemi', array());
		print_r($return);
		exit();


		$r = $bredea->lireTout('dossier');
		//$r = $bredea->lireTout('resa');
		echo "<br><br>";
		print_r($r);
		exit();


		if ($conf && $conf->bredea == 1) {
			try {
				//$bredea = new BredeaSql();
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
				$idResa = 9846;
				$resa =  $this->getResaTable()->getResa($idResa);

				$bredea->testing();
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		exit();
	}

	public function majcodesitesAction()
	{
		$resas = $this->getResaTable()->fetchAll();
		$i = 0;
		foreach ($resas as $resa) {
			if ($resa->idLogement) {
				$residenceDeLogement = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
				if ($residenceDeLogement) {
					$codeSite = $residenceDeLogement->idPMSResidence;
					$this->getResaTable()->updateResa(array('codeSite' => $codeSite), array('id' => $resa->id));
					$i++;
				}
			}
			//exit();
		}
		echo "$i lignes maj";
		exit();
	}

	public function testAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$rows = $this->getResaTable()->getResaBy(array('archive' => '0', 'etat' => 1));
		exit();
		foreach ($rows as $row) {
			if (!$row->idPMS) {
				print_r($row);
				echo "<br><br>";
			}
		}
		exit();

		$loc = $this->getLocatairesTable()->getAllInfos(10291, $adapter);
		print_r($loc);
		exit();

		//$resa = $this->getResaTable()->getListe(8448)->current();
		//print_r($resa);
		include(getcwd().'/externalibs/PDFMerger/PDFMerger.php');

		$pdf = new \PDFMerger();

		$pdf->addPDF(getcwd().'/public/samplepdfs/one.pdf', 'all')
			->addPDF(getcwd().'/public/samplepdfs/two.pdf', 'all')
			->addPDF(getcwd().'/public/samplepdfs/three.pdf', 'all')
			->merge('file', getcwd().'/public/samplepdfs/TEST3.pdf');
		exit();

		$fileArray = array(getcwd()."/public/docs/modeles/output/FACT_20160818.pdf", getcwd()."/public/docs/modeles/output/AVOIR_20160818.pdf");

		$datadir = getcwd()."/public/docs/modeles/output/";
		$outputName = $datadir."merged.pdf";

		$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$outputName ";
		//Add each pdf file to the end of the command
		foreach ($fileArray as $file) {
			$cmd .= $file." ";
		}
		echo $cmd;
		$result = shell_exec($cmd);
		print_r($result);
		exit();

		$idLocataire = $_GET['id'] != "" ? $_GET['id'] : 1;
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter);
		//print_r($loc);
		$modelesFolder = getcwd().'/public/docs/modeles/';

		if (!is_dir(getcwd()."/public/docs/modeles/output")) {
			mkdir(getcwd()."/public/docs/modeles/output");
		}
		$outputFolder = getcwd()."/public/docs/modeles/output/";

		$odf = new odf($modelesFolder.'file2.odt', array('ZIP_PROXY' => 'PhpZipProxy'));

		$odf->setVars('si_nom', 'Mon titre dynamique');

		// Ajouter une image:
		//$odf->setImage('image', 'web-d.jpg');

		//$odf->exportAsAttachedFile("Exemple ODTPHP.odt");
		$odf->saveToDisk($outputFolder.'file2new.odt');

		#### WAIT ####

		$originFilePath = $outputFolder.'file2new.odt';
		$outputDirPath  = $outputFolder;
		Unoconv::convertToPdf($originFilePath, $outputDirPath);

		#### WAIT ####
		header('Content-type: application/pdf');
		header('Content-Disposition: attachment; filename="file2new.pdf"');
		readfile($outputFolder.'file2new.pdf');


		exit();






		//$path = getcwd().'/public/docs/modeles/test.html';
		//$result = file_get_contents($path);

		$htmlOutput = str_replace("%nom%", $loc['nom'], $result);

		//echo $htmlOutput;exit();

		$file = getcwd()."/public/docs/pj/".time().".pdf";
		$pdf = new \TCPDF("", "px", "A4", true, 'UTF-8', false);
		$pdf->setPrintFooter(false);
		$pdf->setPrintHeader(false);
		//$pdf->SetFont('times');

		$pdf->SetAutoPageBreak(true, 10);
		$pdf->SetTopMargin(6);
		$pdf->SetFooterMargin(0);

		$pdf->AddPage();


		$pdf->SetRightMargin(50);
		$pdf->SetLeftMargin(50);

		$pdf->writeHTML($htmlOutput, true, false, true, false, '');

		$pdf->Output("test.pdf", 'D');
		return $file;

		echo $result;
		exit();
	}

	private function getMaxChoix()
	{
		$table = $this->getTableObjet('programme_campagne');
		$select = $table->getSql()->select();
		$select->order(array('maxChoix DESC'));
		$row = $table->selectWith($select)->current();
		$max = $row ? $row->maxChoix : "3";

		return $max;
	}

	private function getCampagneDeResa($resa)
	{
		$idProgramme = !empty($resa->idSousProgramme) ? $resa->idSousProgramme : $resa->idProgramme;
		$tableObj = new Tables('programme_campagne', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select = $tableObj->getTable()->getSql()->select();
		$select->join('campagnes', 'programme_campagne.idCampagne = campagnes.id', array('dateDebut', 'dateFin'));
		$select->where(array('programme_campagne.idProgramme' => $idProgramme));


		$resultSet = $tableObj->getTable()->selectWith($select);
		$resultSet2 = $tableObj->getTable()->selectWith($select);

		$return = "";
		$dateDemandeTS = strtotime(date('Y-m-d', strtotime($resa->dateDemandeReservation)));

		if ($idProgramme) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : resaId=".$resa->id." idLogement=".$resa->idLogement.
				" idProgramme=".$resa->idProgramme."/".$resa->idSousProgramme."/$idProgramme dateDemandeReservation=".$resa->dateDemandeReservation.
				" count1=".count($resultSet)." count2=".count($resultSet2));
		}

		foreach ($resultSet as $row) {
			$dateDebutCampagneTS = strtotime($row->dateDebut);
			$dateFinCampagneTS = strtotime($row->dateFin);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : debut=".$row->dateDebut." fin=".$row->dateFin." idCampagne=".$row->idCampagne);

			if ($dateDemandeTS >= $dateDebutCampagneTS && $dateDemandeTS  <= $dateFinCampagneTS) {
				$return = $row->idCampagne;
				//echo "idResa : ".$resa->id." - camp ".$row->idCampagne."<br>";
			}
		}
		if (!$return) {
			foreach ($resultSet2 as $row) {
				$return = $row->idCampagne;
				//echo "___________idResa : ".$resa->id." - camp ".$row->idCampagne." prog :".$resa->idSousProgramme."<br>";
			}
		}
		if ($return) {
			return $return;
		}

		return false;
	}

	public function appliquerAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");
		$refresh = $this->params()->fromRoute('id', 0);
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			$ids1 = $ids2 = $ids3 = array();
			$ids1 = $request->getPost('champs1');
			$ids2 = $request->getPost('champs2');
			$ids3 = $request->getPost('champs3');
			$ids6 = $request->getPost('champs6'); // dateRenonce && dateRdv
			$idLst = $request->getPost('idLst');

			$limit = (int) $request->getPost('limit');
			$isPlanning = $request->getPost('isPlanning');
			$idCss = $request->getPost('idCss');
			if (empty($limit) || $limit < 0 || $limit > 500) {
				$limit = 500;
			}

			$ilYaDesChampsDynamiques = false;//on verifie si il ya des champs dynamique dans la liste

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champs1=".json_encode($ids1));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champs2=".json_encode($ids2));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champs3=".json_encode($ids3));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champs6=".json_encode($ids6));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLst=".json_encode($idLst));

			/*if($ids1){
				echo "Theme 1 :";
				print_r($ids1);
				}
				if($ids2){
				echo "Theme 2 :";
				print_r($ids2);
				}
				if($ids3){
				echo "Theme 3 :";
				print_r($ids3);
				}
				exit();*/

			//option perdue et duree relance
			$tableC = new Tables('configuration', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$params = $tableC->getTable()->select()->current();

			$optionPerdue = '3';//+3 jours pardefaut
			if ($params->option_perdue) {
				$optionPerdue = $params->option_perdue;
			}
			$dureeRelance = '3';//+3 jours pardefaut
			if ($params->envoie_relance) {
				$dureeRelance = $params->envoie_relance;
			}


			$session = new Container('ListeIds');
			$session->ids1 = $ids1;
			$session->ids2 = $ids2;
			$session->ids3 = $ids3;
			$session->ids6 = $ids6;

			/*$view = new JsonModel(array(
			 'success'=>true,
			 'ids1'=>$ids1,
			 'ids2'=>$ids2,
			 'ids3'=>$ids3,
			 ));

			 $view->setTerminal(true);
			 return($view);*/

			/*****************************/
			//recuperer les champs par code
			$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$tableChamps = $tableObj->getTable();

			$champs = array();
			if ($ids1) {
				foreach ($ids1 as $row) {
					$res = $tableChamps->select(array('code' => $row))->current();
					if ($res) {
						$res->champ = $res->nom;
						$champs[] = $res;
					}
				}
			}

			if ($ids2) {
				foreach ($ids2 as $row) {
					$res = $tableChamps->select(array('code' => $row))->current();
					if ($res) {
						$res->champ = $res->nom;
						$champs[] = $res;
					}

					//extra choix
					/*$numero = str_replace('typeLogement', '', $row);
					if(is_numeric($numero) && $numero > 3){
						$obj = new \stdClass();
						$obj->code = $row;
						$obj->nom = 'Type logement choix '.$numero;
						$champs[] = $obj;
					}*/
				}
			}

			if ($ids3) {
				foreach ($ids3 as $row) {
					$res = $tableChamps->select(array('code' => $row))->current();
					if ($res) {
						$res->champ = $res->nom;
						$champs[] = $res;
					}
				}
			}

			if ($ids6) {
				foreach ($ids6 as $row) {
					$res = $tableChamps->select(array('code' => $row))->current();
					if ($res) {
						$res->champ = $res->nom;
						$champs[] = $res;
					}
				}
			}


			if ($ids1) {
				foreach ($ids1 as $row) {
					//On recupere les champs dynamique
					$champDynamiques = $this->getChampsTable()->getRowByWhere(array('equivalentSql' => $row));
					if ($champDynamiques && $champDynamiques->nature != "standard") {
						$obj = new \stdClass();
						$obj->code = $champDynamiques->equivalentSql;
						$obj->id = $champDynamiques->id;
						$obj->champ = $champDynamiques->libelle;
						$obj->idType = $champDynamiques->idType;//4 doc
						$champs[] = $obj;
						$ilYaDesChampsDynamiques = true;
					}
				}
			}

			//print_r($champs);exit();


			//si on choisi au moins un élément du theme reservation, on affiche les resa sinon on affiche
			// les locataires

			$tables = $champsDeTable = array();
			foreach ($champs as $chm) {
				if (property_exists($chm, 'table') && $chm->table) {
					if (property_exists($chm, 'sourceListe') && $chm->sourceListe) {
						$table = $chm->sourceListe;
					} elseif (property_exists($chm, 'table')) {
						$table = $chm->table;
					}
					$tables[$table] = $table;
				}
			}

			$tablesSql = array();//tables avec champs de chaque table
			foreach ($tables as $tbl) {
				foreach ($champs as $chm) {
					if (property_exists($chm, 'sourceListe') && $chm->sourceListe) {
						$table = $chm->sourceListe;
					} elseif (property_exists($chm, 'table')) {
						$table = $chm->table;
					}
					if ($tbl == $table) {
						if (property_exists($chm, 'equivalentSql') && property_exists($chm, 'code')) {
							$champsDeTable[$chm->code] = $chm->equivalentSql;
						}
					}
				}
				$tablesSql[$tbl] = $champsDeTable;
			}


			//liste des changement de logement demandé
			$where = array();
			$idTypeListe = "";

			if ($idLst) {
				$listeRes = $this->getListesTable()->getListe($idLst);

				if ($listeRes && $listeRes->idType == 6) {
					$idTypeListe = $listeRes->idType;
					$where[] = array('table' => 'reservations', 'champ' => 'idNouvelleResa', 'valeur' => 'NOTNULL');
				}

				if ($listeRes && $listeRes->idType == 3) {
					//liste arriver
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '3', 'predicat' => 'IN');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 2) {
					//liste menage
					$where[] = array('table' => 'reservations', 'champ' => 'idIntercontrat', 'valeur' => 'NOTNULL');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 4) {
					//liste depart
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '7');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 1) {
					//liste demandes
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '1');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 7) {
					//liste groupes
					$where[] = array('table' => 'reservations', 'champ' => 'idGroupeResa', 'valeur' => 'NOTNULL');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 8) {
					//liste pre affectation
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '9');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 9) {
					//liste desistement en cours
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '13');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 10) {
					//liste des demandes en attente
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '11');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 11) {
					//liste des refus
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '4,12', 'predicat' => 'IN');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 12) {
					//liste des affectations
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '2');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				if ($listeRes && $listeRes->idType == 13) {
					//liste des parti sans les changement de logement
					$where[] = array('table' => 'reservations', 'champ' => 'etat', 'valeur' => '6');
					$where[] = array('table' => 'reservations', 'champ' => 'idNouvelleResa', 'valeur' => 'NULL');
					$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
				}

				// $where[] = array('table'=> 'demandes', 'champ'=> 'idModele', 'valeur'=> '7');
			}

			//if($ids2){
			$idTypeListe = $listeRes ? $listeRes->idType : "";
			$rows = $this->getResaTable()->getListe(null, "FR", array('tables' => $tablesSql, 'where' => $where, 'idTypeListe' => $idTypeListe, 'bredea' => $conf->bredea));
			$isResa = true;

			// print_r($rows);die();
			/*}else{
				$rows = $this->getLocatairesTable()->getListe();
				$isResa = false;
			}*/

			//liste state
			$tableObj3 = new Tables('liste_state', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$row = $tableObj3->getTable()->select(array('idListe' => $idLst))->current();

			$data = "{}";
			$dateFilter = "";
			$numberFilter = "";
			if ($row) {
				$data = $row->data;
				$dateFilter = $row->dateFilter;
				$numberFilter = $row->numberFilter;
			}

			//cas rafraichir, on garde l etat courante de la liste
			$session = new Container('listeState');
			if ($session->idListe && $session->idListe == $idLst && $refresh == '1') {
				$data = $session->data;
				$dateFilter = $session->dateFilter;
				$numberFilter = $session->numberFilter;
			}

			## intercontrat
			## on recupere les prochaine resa avec logement pour calculer le risque
			$nexResas = $this->getResaTable()->getNextResas();
			$totalDureeIC = $this->getTotalDureesIC();//le total des duree configuree des etapes
			// pour calculer le risque on fait, totalDuree + ecart et le resultat on l ajoute au date depart
			// puis on calccule la periode entre date fin previsionnelle et le prochain arrivee

			$resaRows = $rows;
			if ($isResa) {
				$resaRows = array();
				foreach ($rows as $r) {
					if ($r->etat == 6 && $this->enIntercontrat($r) && $listeRes && $listeRes->idType == 2) {
						$etatEnCours = $this->getEtatIntercontratTable()->select(array('id' => $r->idIntercontrat))->current();
						$etatICResult = $this->getIntercontratTable()->select(array('idReservation' => $r->id));
						/* ADDED BY WADIE TO AVOID PARTI */
						$r->etatIntercontrat = $etatEnCours->nom;
						/* ADDED BY WADIE TO AVOID PARTI */
						$ecart = 0;
						foreach ($etatICResult as $etatIC) {
							if ($r->idIntercontrat == $etatIC->idEtat) {
								$decalage = $dureeReel = 0;
								if ($etatIC && $etatIC->dateEtat) {
									$dateDebut = new \DateTime(date('Y-m-d'));
									$dateFin = new \DateTime($etatIC->dateEtat);
									$difference = $dateDebut->diff($dateFin);
									$dureeReel = $difference->format('%a');

									$dureeConfig = $this->getDuree($r->id, $r->idIntercontrat);
									$decalage = $dureeReel - $dureeConfig;
								}

								$texte = "";
								if ($decalage > 0) {
									$texte .= "<i class='fa fa-exclamation-triangle yellow'></i>$dureeReel j ";
									$ecart += $decalage;
								}
								$texte .= $etatEnCours->nom;
								$r->etatIntercontrat = $texte;
							} else {
								$ecart += abs($etatIC->decalage);
							}
						}
						$r->ecart = $ecart;
						## calcule risque
						$dureeRestante = $totalDureeIC + $ecart;
						if ($dureeRestante > 0) {
							$dateFin = date('Y-m-d', strtotime($r->dateDepart." + $dureeRestante day"));
						} else {
							$dateFin = date('Y-m-d', strtotime($r->dateDepart." - $dureeRestante day"));
						}
						//on cherche la prochaine resa
						$nextResa = !empty($nexResas[$r->idLogement]) ? $nexResas[$r->idLogement] : null;
						//on clacule la difference entre la date fin et la nouvelle resa
						if ($nextResa) {
							$debut = new \DateTime($dateFin);
							$fin = new \DateTime($nextResa->dateArrivee);
							$difference = $debut->diff($fin);
							$r->risque = $difference->format('%a');
							//si la date debut > date fin , le risque sera negatif
							if (strtotime($dateFin) > strtotime($nextResa->dateArrivee)) {
								$r->risque = $r->risque * (-1);
							}
						} else {
							$r->risque = 999;//pas de nouvelle resa prevue
						}
					}

					if (!empty($listeRes) && property_exists($listeRes, 'idType') && $listeRes->idType == 1 && !empty($r) && property_exists($r, 'etat') && $r->etat != 1 && $r->etat != 10) {
						continue;
					}

					$resaRows[] = $r;
				}
			}
			$rows = $resaRows;

			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$rowsFinal = array();

			//$allInfosBredea = $this->readAllBredeaInfos();//demandes, resas et dossiers
			if ($ilYaDesChampsDynamiques) {
				$dynamiqueFieldsValue = $this->getLocatairesTable()->getAllInfosDynamiqueForLocs($adapter);
			}

			foreach ($rows as $row) {
				$idLocataire = $row->idLocataire;
				//$extraLoc = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($idLocataire, $adapter);
				$extraLoc = array();
				if ($ilYaDesChampsDynamiques) {
					//$extraLoc = $dynamiqueFieldsValue[$idLocataire];
					$extraLoc = $dynamiqueFieldsValue[$row->id];
				}

				$resaArray = get_object_vars($row);
				if (!empty($extraLoc)) {
					$all = array_merge($extraLoc, $resaArray);
				} else {
					$all = $resaArray;
				}


				##BREDEA

				$site = $row->codeSite;
				if ($site) {
					if ($row->numDossier) {
						$numero = $row->numDossier;
						$allBredeaRows = !empty($allInfosBredea['dossiers']) ? $allInfosBredea['dossiers'] : array();
					} elseif ($row->numResa) {
						$numero = $row->numResa;
						$allBredeaRows = !empty($allInfosBredea['resas']) ? $allInfosBredea['resas'] : array();
					} elseif ($row->idPMS) {
						$numero = $row->idPMS;
						$allBredeaRows = !empty($allInfosBredea['demandes']) ? $allInfosBredea['demandes'] : array();
					}
					$numero = (int) $numero;
					$customKey = $numero.'_'.$site;

					$rowBredea = array_key_exists($customKey, $allBredeaRows) ? $allBredeaRows[$customKey] : array();

					if (!empty($rowBredea)) {
						//print_r($rowBredea);exit();
						foreach ($rowBredea as $champ => $val) {
							if (trim($val) != "") {
								$all[$champ] = utf8_encode($val);
								if (array_key_exists($champ.'Locataire', $all)) {
									$all[$champ.'Locataire'] = utf8_encode($val);
								}
							}
						}
						//print_r($all);exit();
					}
				}

				//on verifie si changement de logement (meme dossier) :
				//on affiche pas la date depart bredea pour l ancienne resa
				//on affiche pas la date arrivee bredea pour la nouvelle resa
				if ($row->idNouvelleResa) {
					//on cherche la nouvelle resa pour verifie si les deux resa on le meme dossier
					$nr = $this->getResaTable()->getResa($row->idNouvelleResa);
					if ($nr && $nr->numDossier == $row->numDossier) {
						$all['dateDepart'] = $row->dateDepart;
					} elseif ($nr && $nr->etat == 15) {
						//si la resa est en cours de changement
						$all['etatReservation'] .= " - en cours de changement ".$nr->numeroChambre."";
						$all['dateDepart'] = $row->dateDepart;
					}
				}
				if ($row->idAncienneResa) {
					//on cherche l ancienne resa pour verifie si les deux resa on le meme dossier
					$nr = $this->getResaTable()->getResa($row->idAncienneResa);
					if ($nr && $nr->numDossier == $row->numDossier) {
						$all['dateArrivee'] = $row->dateArrivee;
					}
				}

				$rowsFinal[] = $all;
			}

			$intercontrats = $this->getRealEtatintercontratTable()->fetchAll();

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/afficher')
			->setVariables(array(
					'rows' => $rowsFinal,
					'themes' => $champs,
					'isResa' => $isResa,
					'idListe' => $idLst,
					'idTypeListe' => $idTypeListe,
					'data' => $data,
					'dateFilter' => $dateFilter,
					'numberFilter' => $numberFilter,
					'optionPerdue' => $optionPerdue,
					'dureeRelance' => $dureeRelance,
					'choixTable' => $this->getChoixTable(),
					'resaTable' => $this->getResaTable(),
					'isPlanning' => $isPlanning,
					'idCss' => $idCss,
					'intercontrats' => $intercontrats,
			));


			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						'champs' => $champs,
						  'htmlOP' => $htmlOutput,
						'idListe' => $idLst,
						'data' => $data,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function savestateAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$data		= $request->getPost('data');
			$idListe	= $request->getPost('idListe');
			$dateFilter	= $request->getPost('dateFilter');
			$numberFilter	= $request->getPost('numberFilter');

			$session = new Container('listeState');
			$session->idListe = $idListe;
			$session->data = $data;

			$dataObj	= json_decode($data);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe dataTime=".date("H:i:s", $dataObj->time));

			if (property_exists($dataObj, 'ColReorder') && $session->ColReorder != $dataObj->ColReorder) {
				$session->ColReorder	= $dataObj->ColReorder;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : new ColReorder=".json_encode($dataObj->ColReorder));
			}
			if ($session->dateFilter != $dateFilter) {
				$session->dateFilter = $dateFilter;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : new dateFilter=$dateFilter");
			}
			if ($session->numberFilter != $numberFilter) {
				$session->numberFilter = $numberFilter;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : new numberFilter=$numberFilter");
			}

			/*$tableObj3 = new Tables('liste_state',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$row = $tableObj3->getTable()->select(array('idListe'=>$idListe))->current();

			if($row){
			$types = $tableObj3->getTable()->update(array('data'=>$data),array('idListe'=>$idListe));
			}else{
			$types = $tableObj3->getTable()->insert(array('data'=>$data,'idListe'=>$idListe));
			}*/


			$view = new JsonModel(array(
						'success' => true,
						'op' => $data,


			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadstateAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		if ($request->isXmlHttpRequest()) {
			$data = $request->getPost('data');
			$view = new JsonModel(array(
						'success' => true,
						'op' => $data,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadsprogAction()
	{
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			$idProg = (int) $request->getPost('id');
			$idCampagne = (int) $request->getPost('idCampagne');
			$sp = array();
			if ($idProg > 0) {
				if ($conf->modeRecupProgCampagne == 'idProgramme') {
					$result = $this->getProgrammeTable()->getSousProgrammes($idProg);
				} elseif ($idCampagne > 0 && $conf->modeRecupProgCampagne == 'idSousProgramme') {
					$result = $this->getProgrammeTable()->getSPDeCampagnes($idProg, $ids);
				} else {
					$result = $this->getProgrammeTable()->getSousProgrammes($idProg);
				}

				if ($result->count() <= 0) {
					$result = $this->getProgrammeTable()->getProgrammeById($idProg);

					$sp[$result->id] = $result->nom;
				} else {
					$prog = $this->getProgrammeTable()->getProgrammeById($idProg);
					if ($prog) {
						$sp[$prog->id] = $prog->nom;
					}
					foreach ($result as $r) {
						$sp[$r->id] = $r->nom;
					}
				}
			} else {
				$sp = false;
			}

			$view = new JsonModel(array(
					'sp' => $sp,
					'success' => true,
			));


			$view->setTerminal(true);
			return $view;
		}
	}

	public function apercuAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$htmlOutput = "";
		if ($request->isXmlHttpRequest()) {
			$href = $request->getPost('href');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] href=$href");
			// echo "$href:".$href;
			// die();

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/apercu')
			->setVariables(array(
					'href' => $href,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function apercupjAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$htmlOutput = "";
		if ($request->isXmlHttpRequest()) {
			$href = $request->getPost('href');
			$docId = $request->getPost('docId', false);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/apercupj')
			->setVariables(array(
					'href' => $href,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function loadmailAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$tools = new Tools();

		$htmlOutput = "";
		if ($request->isXmlHttpRequest()) {
			$id = $request->getPost('id');

			$mail = $this->getHistoriquemailTable()->getHistorique($id);
			$htmlOutput = "";
			if ($mail) {
				$file = getcwd()."/public/docs/locataires/".$mail->idLocataire."/mailing/".$id."/corps.html";
				if (file_exists($file)) {
					$htmlOutput = $tools->readFile($file);
				}
				if (!$htmlOutput) {
					$htmlOutput = $mail->message;
				}
			}

			$view = new JsonModel(array(
				'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Confirmation pour archiver tous les membres du ménages des résas cochées
	public function archiverResasMenagesAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$isResa = $request->getPost('isResa');
			$typeListe = $request->getPost('typeListe');

			if ($isResa == '1') {

				$html = '';

				foreach ($ids as $idResa) {

					$dossier = '';

					$sqlResa = "SELECT 
							reservations.id AS id,
							reservations.idLocataire AS idLocataire,
							locataires.nom AS nomLoc,
							locataires.prenom AS prenomLoc,
							reservations.idStatutFamilial AS idStatutFamilial,
							statut_familial.nom AS statutF,
							reservations.idMenage AS idMenage,
							menages.nom AS men,
							reservations.idCampagne AS idCampagne,
							campagnes.nom AS campagne,
							reservations.residenceOrientation AS residenceOrientation,
							residences.id AS idResidence
						FROM reservations
							LEFT JOIN locataires ON locataires.id = reservations.idLocataire
							LEFT JOIN statut_familial ON statut_familial.id = reservations.idStatutFamilial
							LEFT JOIN menages ON menages.id = reservations.idMenage
							LEFT JOIN campagnes ON campagnes.id = reservations.idCampagne
							LEFT JOIN logements ON logements.id = reservations.idLogement
							LEFT JOIN batiments ON batiments.id = logements.idBatiment
							LEFT JOIN residences ON residences.id = batiments.idResidence
						WHERE reservations.id = $idResa";

					$resultResa = $adapter->query($sqlResa)->execute();
					$resa = (object) $resultResa->current();

					$statutFamilial = '';
					if ($resa && $resa->statutF != '') {
						$statutFamilial = ' - '.$resa->statutF;
					}

					$menage = '';
					if ($resa && $resa->men != '') {
						$menage = ' ('.$resa->men.')';
					}

					$res = '';
					if ($resa->residenceOrientation != '') {
						$residence = $this->getTableObjet('residences')->select(array('id' => $resa->residenceOrientation))->current();
						if ($residence && $residence->nom) {
							$res = ' - '.$residence->nom;
						}
					} elseif ($resa->idResidence != '') {
						$residence = $this->getTableObjet('residences')->select(array('id' => $resa->idResidence))->current();
						if ($residence && $residence->nom) {
							$res = ' - '.$residence->nom;
						}
					}

					$camp = '';
					if ($resa && $resa->campagne != '') {
						$camp = ' ('.$resa->campagne.')';
					}

					$dossier = $resa->nomLoc." ".$resa->prenomLoc.$statutFamilial.$menage.$res.$camp;

					$html .= '<label for="personne"><input type="checkbox" name="personne" checked data-idresa="'.$resa->id.'" id="'.$resa->id.'" /> '.$dossier.'</label></br>';

					## Si on est dans une liste de type Famille et que la résa cochée est un chef de famille, proposer d'archiver tous les membres du ménages sur la même résidence et campagne
					if ($typeListe == 23 && $resa->idStatutFamilial == 1 && $resa->idMenage > 0) {

						$sqlResasMenages = "SELECT 
								reservations.id AS id,
								reservations.idLocataire AS idLocataire,
								locataires.nom AS nomLoc,
								locataires.prenom AS prenomLoc,
								statut_familial.nom AS statutF,
								menages.nom AS men,
								campagnes.nom AS campagne,
								reservations.residenceOrientation AS residenceOrientation,
								residences.id AS idResidence
							FROM reservations
								LEFT JOIN locataires ON locataires.id = reservations.idLocataire
								LEFT JOIN statut_familial ON statut_familial.id = reservations.idStatutFamilial
								LEFT JOIN menages ON menages.id = reservations.idMenage
								LEFT JOIN campagnes ON campagnes.id = reservations.idCampagne
								LEFT JOIN logements ON logements.id = reservations.idLogement
								LEFT JOIN batiments ON batiments.id = logements.idBatiment
								LEFT JOIN residences ON residences.id = batiments.idResidence
							WHERE reservations.idMenage = $resa->idMenage AND reservations.idStatutFamilial != '1' AND reservations.idCampagne = $resa->idCampagne";

						if ($resa->residenceOrientation != '') {
							$sqlResasMenages .= " AND reservations.residenceOrientation = $resa->residenceOrientation";
						} elseif ($resa->idResidence != '') {
							$sqlResasMenages .= " AND residences.id = $resa->idResidence";
						}

						$resasMenage = array();
						$results = $adapter->query($sqlResasMenages)->execute();
						foreach ($results as $result) {
							## Si le membre du ménage n'est pas déjà coché, l'ajouter aux propositions
							if (!in_array($result['id'], $ids)) {
								$resasMenage[] = (object) $result;
							}
						}

						foreach ($resasMenage as $resaMenage) {
							$dossier = '';

							$statutFamilial = '';
							if ($resaMenage->statutF && $resaMenage->statutF != '') {
								$statutFamilial = ' - '.$resaMenage->statutF;
							}

							$menage = '';
							if ($resaMenage->men && $resaMenage->men != '') {
								$menage = ' ('.$resaMenage->men.')';
							}

							$res = '';
							if ($resaMenage->residenceOrientation != '') {
								$residence = $this->getTableObjet('residences')->select(array('id' => $resaMenage->residenceOrientation))->current();
								if ($residence && $residence->nom) {
									$res = ' - '.$residence->nom;
								}
							} elseif ($resaMenage->idResidence != '') {
								$residence = $this->getTableObjet('residences')->select(array('id' => $resaMenage->idResidence))->current();
								if ($residence && $residence->nom) {
									$res = ' - '.$residence->nom;
								}
							}

							$camp = '';
							if ($resaMenage && $resaMenage->campagne != '') {
								$camp = ' ('.$resaMenage->campagne.')';
							}

							$dossier = $resaMenage->nomLoc." ".$resaMenage->prenomLoc.$statutFamilial.$menage.$res.$camp;
							$html .= '<label for="personne"><input type="checkbox" name="personne" checked data-idresa="'.$resaMenage->id.'" id="'.$resaMenage->id.'" /> '.$dossier.'</label></br>';
						}
					}
				}
			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");
				$msg = "- Pas une réservation";
			}

			$view = new JsonModel(array('success' => $success, 'msg' => $msg, 'html' => $html));
			$view->setTerminal(true);
			return $view;
		}
	}

	## Archivage une reservation
	public function archiverresaAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$conf = $this->getConfigurationTable()->getConfig(1);
		$session = new Container('listeNonArchivee');
		$session->idsNonArchivee = null;
		$session->idsNonSupprimer = null;

		if ($request->isXmlHttpRequest()) {
			$idReservation = $request->getPost('idResa');
			$isResa = $request->getPost('isResa');
			$typeListe = $request->getPost('typeListe');
			$listeCSV = $request->getPost('listeCSV');
			$msg = $msgParResa = "";

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa idResa=$idResa typeListe=$typeListe");

			$ids = array();
			if ($idReservation && !is_array($idReservation)) {
				$ids[] = $idReservation;
			} elseif (is_array($idReservation)) {
				$ids = $idReservation;
			}

			$idsArchivee = $idsNonArchivee = array();
			$etatArchive = array();

			// var_dump($ids);die();
			$resasNeedFielsArchive = [];

			if ($isResa == '1') {
				//foreach ($ids as $idResa) {
				for($i = 0;$i < sizeof($ids);$i++) {
					$idResa = $ids[$i];
					// var_dump($idResa);
					$archive = false;

					## Bredea :
					# on verifie que le compte et la caution sont à Zéro,
					# Si différent de 0 tu met un message d’erreur qui dit que son compte n’est pas à zéro
					# et on affiche le solde du compte

					$resa = $this->getResaTable()->getResaEtLoc($idResa);
					$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($resa->idLocataire, $adapter, $idResa, 0);
					$resaArr = get_object_vars($resa);
					unset($resaArr['id']);
					$locAllInfosObj = array_merge($locAllInfosObj, $resaArr);

					$allFielObligatoireArchiveOk = true;
					$idsChampsActions = $this->getChampsLiesAuxActions($resa->idCampagne);
					$champsObligatoireLieAuxActions = array();

					// pour chaque reservation on regarde si on a des champs obligatoire non rempli
					$formulaires = $this->getTableObjet('formulaires')
					->select(array('idCampagne' => $resa->idCampagne))->toArray();

					if (count($formulaires) > 0) {
						foreach ($formulaires as $key => $f) {
							$champs_formulaires = $this->getTableObjet('champs_formulaires')
							->select(array('idFormulaire' => $f['id'], 'obligatoireArchivage' => '1'))
							->toArray();

							if (count($champs_formulaires) > 0) {
								$champsArchiveNotOk = [];
								foreach ($champs_formulaires as $key => $cf) {
									// on vérifie si on a une valeur
									$champVide = false;
									if($cf['nature'] == 'libre') {
										$vd = $this->getTableObjet('valeurs_dynamiques')
										->select(array('idChamp' => $cf['id'], 'idReservation' => $idResa))->current();
										if (!$vd || $vd->valeur == '') {
											$champsArchiveNotOk[$cf['id']] = $cf;
											$champVide = true;
										}
									} elseif($cf['nature'] == 'standard') {
										if(array_key_exists($cf['equivalentSql'], $locAllInfosObj)) {
											$valChamp = $locAllInfosObj[$cf['equivalentSql']];
											if($valChamp == null || $valChamp == '' || ($cf['idType'] == 2 && substr($valChamp, 0, 2) == '00')) {
												$champsArchiveNotOk[$cf['id']] = $cf;
												$champVide = true;
											}
										}
									}
									if($champVide){
										$cfObj = (object)$cf;
										if (in_array($cfObj->id, $idsChampsActions)) {
											$champsObligatoireLieAuxActions[$cfObj->id] = $cfObj;
										}
									}
								}//end foreach champs_formulaires

								// tous les champs obligatoires pour l'archivage sont vides
								if (count($champsArchiveNotOk) > 0) {
									$resa->champsVides = $champsArchiveNotOk;
									$allFielObligatoireArchiveOk = false;
								}
							}
						}
						## vérification actions
						if(!empty($champsObligatoireLieAuxActions)){
							$actions = $this->getAllActions($resa);
							$idsChampsHidden = array();
							if(!empty($actions['hide'])){
								//on regarde si un des champs obligatoire archivage n'est pas caché par une condition
								foreach($champsObligatoireLieAuxActions as $idC=>$cObj){
									if(in_array($idC,$actions['hide'])){
										$idsChampsHidden[] = $idC;
									}
								}
							}
							if(!empty($idsChampsHidden)){
								foreach($champsArchiveNotOk as $idCf=>$cf){
									if(in_array($idCf,$idsChampsHidden)){
										unset($champsArchiveNotOk[$idCf]);
									}
								}
								//re vérification
								if (count($champsArchiveNotOk) <= 0) {
									$resa->champsVides = null;
									$allFielObligatoireArchiveOk = true;
								}
							}
						}
						## FIN vérification actions
					}


					/*if($typeListe == 23 && $resa->idStatutFamilial == 1 && $resa->idMenage > 0){
						$resasMembresMenageNonValide = array();
						//on verifie si tout les champs obligatoire archivage de tout les membre de ce ménage sont remplis
						$membresMenage = $this->getResaTable()->getMembresMenageNonArchive($resa->idMenage,true);
						foreach($membresMenage as $mm){
							$idResaM = $mm->id;
							if($idResaM == $idResa){
								continue;
							}
							$idsResasMembres[$idResaM] = $idResaM;
							$resaM = $this->getResaTable()->getResaEtLoc($idResaM);
							$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($resaM->idLocataire, $adapter, $idResaM, 0);
							$resaArr = get_object_vars($resa);
							unset($resaArr['id']);
							$locAllInfosObj = array_merge($locAllInfosObj,$resaArr);

							$allFielObligatoireArchiveOk_M = true;

							// pour chaque reservation on regarde si on a des champs obligatoire non rempli
							$formulaires = $this->getTableObjet('formulaires')
							->select(array('idCampagne' => $resaM->idCampagne))->toArray();

							if (count($formulaires) > 0) {
								foreach ($formulaires as $key => $f) {
									$champs_formulaires = $this->getTableObjet('champs_formulaires')
									->select(array('idFormulaire' => $f['id'], 'obligatoireArchivage' => '1'))
									->toArray();

									if (count($champs_formulaires) > 0) {
										$champsArchiveNotOk = [];
										foreach ($champs_formulaires as $key => $cf) {
											// on vérifie si on a une valeur
											if($cf['nature']=='libre'){
												$vd = $this->getTableObjet('valeurs_dynamiques')
												->select(array('idChamp' => $cf['id'], 'idReservation' => $idResaM))->current();
												if (!$vd || $vd->valeur == '') {
													$champsArchiveNotOk[] = $cf;
												}
											}elseif($cf['nature']=='standard'){
												if(array_key_exists($cf['equivalentSql'],$locAllInfosObj)){
													$valChamp = $locAllInfosObj[$cf['equivalentSql']];
													if($valChamp==null || $valChamp == '' ||($cf['idType'] == 2 && substr($valChamp,0,2)=='00')){
														$champsArchiveNotOk[] = $cf;
													}
												}
											}
										}

										// tous les champs obligatoires pour l'archivage sont vides
										if (count($champsArchiveNotOk) > 0) {
											$resaM->champsVides = $champsArchiveNotOk;
											$allFielObligatoireArchiveOk_M = false;
										}
									}
								}
							}
							if(!$allFielObligatoireArchiveOk_M){
								array_push($resasNeedFielsArchive, $resaM);
								$resasMembresMenageNonValide[$idResaM] = $resaM;

								$champVidesLib = "Champs vides: ";
								foreach ($resaM->champsVides as $key => $cvl) {
									$champVidesLib .= " -".$cvl['libelle']." ";
								}

								$msgParResa = "- Erreur archivage réservation de chef de famille($idResa) ".$resa->nomLocataire." ".$resa->prenomLocataire." (champs obligatoires archivage vides) du membre($idResaM) ".$resaM->nomLocataire." ".$resaM->prenomLocataire."<br>";
								$msg .= $msgParResa;
								$etatArchive['ko']=true;
								$idsNonArchivee[$idResaM] = array(
												'idResa'=>$idResaM,
												'nomLocataire'=>$resaM->nomLocataire,
												'prenomLocataire'=>$resaM->prenomLocataire,
												'numeroChambre'=>$resaM->numeroChambre,
												'erreur'=>$msgParResa,
												'champsVides' => $champVidesLib
											);
							}

						}//end foreach memebreMenage

						if(!empty($resasMembresMenageNonValide)){
							continue;
						}else{
							foreach($idsResasMembres as $idResaMM){
								if(!in_array($idResaMM,$ids)) array_push($ids, $idResaMM);
							}
						}
					}*/

					//print_r($ids);exit();

					if (!$allFielObligatoireArchiveOk) {
						array_push($resasNeedFielsArchive, $resa);

						$champVidesLib = "Champs vides: ";
						foreach ($resa->champsVides as $key => $cvl) {
							$champVidesLib .= " -".$cvl['libelle']." ";
						}

						$msgParResa = "- Erreur archivage réservation($idResa)(champs obligatoires archivage vides) de ".$resa->nomLocataire." ".$resa->prenomLocataire."<br>";
						$msg .= $msgParResa;
						$etatArchive['ko'] = true;
						$idsNonArchivee[$idResa] = array(
										'idResa' => $idResa,
										'nomLocataire' => $resa->nomLocataire,
										'prenomLocataire' => $resa->prenomLocataire,
										'numeroChambre' => $resa->numeroChambre,
										'erreur' => $msgParResa,
										'champsVides' => $champVidesLib,
									);
						continue;
					}


					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idPMS=".$resa->idPMS);
					if ($conf && $conf->bredea == 1 && ($resa->idPMS || $resa->numDossier || ($resa->codeSite && $resa->codeSite != $conf->siteDemande) || $resa->numResa)) {
						try {
							$bredea		= null;
							if ($resa->idPMS || $resa->numDossier || $resa->numResa) {
								$this->initPMS($resa->idApiPms ?: 1, $idResa);

								## Traitement en fonction du PMS
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->pms) {
									if ($this->pms->getClassName() === "Bredea") {
										$bredea		= $this->pms;
									} elseif ($this->pms->getClassName() === "CeriFoyer") {
										$errMsg	= $this->pms->archiverResa($resa);
										if ($errMsg) {
											$msgParResa	= "- Vous ne pouvez pas archiver cette réservation($idResa) de ".$resa->nomLocataire." ".$resa->prenomLocataire.", $errMsg<br>";
											$msg		.= $msgParResa;
										} else {
											$archive	= true;
										}
									}
								}
							}else{
								## pas dans le PMS
								$archive	= true;
							}
							if ($bredea) {
								##viaPMS $bredea = new BredeaSql($conf->siteDemande);
								if ($resa->numDossier && $resa->codeSite) {
									$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre,'mode'=>'rmbDG');
									$soldes = $bredea->getSoldeDossier($cData);
									//print_r($soldes);exit();

									if (!empty($soldes)) {
										$soldeCompte = !empty($soldes['soldeCompte']) ? $soldes['soldeCompte'] : 0;
										$soldeCaution = !empty($soldes['soldeCaution']) ? $soldes['soldeCaution'] : 0;
										if ($soldeCompte == 0 && $soldeCaution == 0) {
											# on archive
											$cData['type'] = 'dossier';
											$archive = $bredea->archiver($cData);
										} else {
											if ($soldeCompte != 0) {
												$msgParResa = "- Vous ne pouvez pas archiver cette réservation($idResa) de ".$resa->nomLocataire." ".$resa->prenomLocataire.", SOLDE COMPTE $soldeCompte<br>";
												$msg .= $msgParResa;
											}
											if ($soldeCaution != 0) {
												$msgParResa = "- Vous ne pouvez pas archiver cette réservation($idResa) de ".$resa->nomLocataire." ".$resa->prenomLocataire.", SOLDE CAUTION $soldeCaution<br>";
												$msg .= $msgParResa;
											}
										}
									} else {
										//pas de factures
										$cData['type'] = 'dossier';
										$archive = $bredea->archiver($cData);
									}
								} elseif ($resa->numResa && $resa->codeSite) {
									$cData = array('numResa' => $resa->numResa, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
									$cData['type'] = 'resa';
									$archive = $bredea->archiver($cData);
								} elseif ($resa->idPMS) {
									$cData = array('numDemande' => $resa->idPMS, 'typre' => $resa->typre, 'codeSite' => $resa->codeSite);
									$cData['type'] = 'demande';
									$archive = $bredea->archiver($cData);
								} elseif (!$resa->idPMS) {
									//pas dans bredea
									$archive = true;
								}
								$bredea->closeConnect();
								$this->pms	= null;
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception msg=".$ex->getMessage());
						}
					} else {
						$archive = true;
					}

					if ($archive) {
						try {
							// on archive cote wl
							$dateArchive = date('Y-m-d');
							$this->getResaTable()->updateResa(array('archive' => '1', 'dateArchive' => $dateArchive), array('id' => $idResa));
							// on archive cote wl
							//si resa de groupe on supprime toutes les resa

							if ($typeListe == 7 && $resa->idGroupeResa) {
								$this->getResaTable()->updateResa(array('archive' => '1', 'dateArchive' => $dateArchive), array('idGroupeResa' => $resa->idGroupeResa));
								$this->getTableObjet('reservations_groupe')->update(array('archive' => '1'), array('id' => $resa->idGroupeResa));
							}
							$msg .= "- Réservation ($idResa) de ".$resa->nomLocataire." ".$resa->prenomLocataire." bien archivée<br>";
							## on verife si la resa est dans la pile on l enleve
							$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $idResa))->current();
							if ($pile) {
								$this->getTableObjet('pile_paiement')->delete(array('id' => $pile->id));
							}
							$idsArchivee[$idResa] = $archive;
							$etatArchive['ok'] = true;

							//envois de mail
							$this->envoyerMail($idResa, 11);

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO Archivage réservation $idResa";
							$log->dataBefore = array('archive' => '0');
							$log->dataAfter = array('archive' => '1');
							$log->tableName = "reservations";
							$log->idReservation = $idResa;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception msg=".$ex->getMessage());
						}
					} else {
						if ($msg == "") {
							$msgParResa = "- Erreur archivage réservation($idResa) de ".$resa->nomLocataire." ".$resa->prenomLocataire."<br>";
							$msg .= $msgParResa;
						}
						$etatArchive['ko'] = true;
						$idsNonArchivee[$idResa] = array(
										'idResa' => $idResa,
										'nomLocataire' => $resa->nomLocataire,
										'prenomLocataire' => $resa->prenomLocataire,
										'numeroChambre' => $resa->numeroChambre,
										'erreur' => $msgParResa,
										'champsVides' => '',
									);
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa msg=$msg");
				}
			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");
				$msg = "- Pas une réservation";
			}
			$success	= ($msg != '');

			$msgCss = "alert-success";
			if (array_key_exists('ok', $etatArchive) && array_key_exists('ko', $etatArchive)) {
				$msgCss = "alert-warning";
			} elseif (array_key_exists('ko', $etatArchive) && !array_key_exists('ok', $etatArchive)) {
				$msgCss = "alert-danger";
			}

			$csv = false;
			if ($listeCSV != "" && !empty($idsNonArchivee)) {
				//générer la liste des demandes non archive au format csv
				$session->idsNonArchivee = $idsNonArchivee;
				$csv = true;
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : success=$success msg=$msg");
			$view = new JsonModel(array(
				'success' => $success,
						  'msg' => $msg,
						  'resasNeedFielsArchive' => $resasNeedFielsArchive,
						  'idsArchivee' => $idsArchivee,
						  'msgCss' => $msgCss,
						  'csv' => $csv,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## export de la liste des demandes non archive avec la cause
	public function exportlistenonarchiveAction()
	{
		$session = new Container('listeNonArchivee');
		$resas = array();
		$titre = 'Liste_non_archivee_';
		if (!empty($session->idsNonArchivee)) {
			$resas = $session->idsNonArchivee;
		} elseif (!empty($session->idsNonSupprimer)) {
			$resas = $session->idsNonSupprimer;
			$titre = 'Liste_non_supprimer_';
		}
		$header = array('idReservation', 'Nom', 'Prénom', 'Numéro de chambre', 'Erreur', 'Champs vides');
		$finalData = array();
		foreach ($resas as $idResa => $ligne) {
			$finalData[] = $ligne;
		}
		return $this->csvExport($titre.date('d-m-Y-His').'.csv', $header, $resas);
	}

	## Supprimer une reservation archivé
	public function deleteresaAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$conf = $this->getConfigurationTable()->getConfig(1);
		$session = new Container('listeNonArchivee');
		$session->idsNonArchivee = null;
		$session->idsNonSupprimer = null;

		$tableVD = $this->getTableObjet('valeurs_dynamiques');
		$tableSuivis = $this->getTableObjet('suivis');
		$tableSuivisVD = $this->getTableObjet('suivis_values');
		$tableDocs = $this->getTableObjet('documents');
		$tableDocsResa = $this->getTableObjet('document_locataire');

		if ($request->isXmlHttpRequest()) {
			$idReservation = $request->getPost('idResa');
			$isResa = $request->getPost('isResa');
			$typeListe = $request->getPost('typeListe');
			$listeCSV = $request->getPost('listeCSV');
			$msg = $msgParResa = "";

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa idResa=$idResa typeListe=$typeListe");

			$ids = array();
			if ($idReservation && !is_array($idReservation)) {
				$ids[] = $idReservation;
			} elseif (is_array($idReservation)) {
				$ids = $idReservation;
			}

			$idsSupprimer = $idsNonSuppimer = array();
			$etatSuppression = array();

			if ($isResa == '1') {
				foreach ($ids as $idResa) {
					$deleted = false;

					## Bredea :
					# on verifie que le compte et la caution sont à Zéro,
					# Si différent de 0 tu met un message d’erreur qui dit que son compte n’est pas à zéro
					# et on affiche le solde du compte

					$resa = $this->getResaTable()->getResaEtLoc($idResa);
					$resaWL = $this->getResaTable()->getResa($idResa);

					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idPMS=".$resa->idPMS);
					if ($conf && $conf->bredea == 1 && ($resa->idPMS || $resa->numDossier || $resa->codeSite || $resa->numResa)) {
						try {
							$bredea		= null;
							if ($resa->idPMS || $resa->numDossier || $resa->numResa) {
								$this->initPMS($resa->idApiPms ?: 1, $idResa);

								## Traitement en fonction du PMS
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->pms) {
									if ($this->pms->getClassName() === "Bredea") {
										$bredea		= $this->pms;
									} elseif ($this->pms->getClassName() === "CeriFoyer") {
										//a faire pour CERI
										$deleted = true;
									}
								}
							}
							if ($bredea) {
								##viaPMS $bredea = new BredeaSql($conf->siteDemande);
								if ($resa->numDossier && $resa->codeSite) {
									$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
									$cData['type'] = 'dossier';
									$deleted = $bredea->supprimerResa($cData);
								} elseif ($resa->numResa && $resa->codeSite) {
									$cData = array('numResa' => $resa->numResa, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
									$cData['type'] = 'resa';
									$deleted = $bredea->supprimerResa($cData);
								} elseif ($resa->idPMS) {
									$cData = array('numDemande' => $resa->idPMS, 'typre' => $resa->typre);
									$cData['type'] = 'demande';
									$deleted = $bredea->supprimerResa($cData);
								} elseif (!$resa->idPMS) {
									//pas dans bredea
									$deleted = true;
								}
								$bredea->closeConnect();
								$this->pms	= null;
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception msg=".$ex->getMessage());
						}
					} else {
						$deleted = true;
					}

					if ($deleted) {
						try {
							// on supprime cote wl
							$this->getResaTable()->deleteResa($idResa);
							// on supprime cote wl
							//si resa de groupe on supprime toutes les resa
							if ($typeListe == 7 && $resa->idGroupeResa) {
								$this->getResaTable()->deleteResaBy(array('idGroupeResa' => $resa->idGroupeResa));
								$this->getTableObjet('reservations_groupe')->delete(array('id' => $resa->idGroupeResa));
							}

							$msg .= "- Réservation ($idResa) bien supprimée<br>";
							## on verife si la resa est dans la pile on l enleve
							$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $idResa))->current();
							if ($pile) {
								$this->getTableObjet('pile_paiement')->delete(array('id' => $pile->id));
							}
							$idsSupprimer[$idResa] = $deleted;
							$etatSuppression['ok'] = true;

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO suppression définitif de la réservation $idResa";
							$log->dataBefore = $resaWL;
							$log->dataAfter = array();
							$log->tableName = "reservations";
							$log->idReservation = $idResa;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);

							## on supprime les valeurs dynamiques
							## on supprime des valeurs dynamiques
							$result = $tableVD->select(array('idReservation' => $idResa));
							if ($result->count() > 0) {
								$vals = $result->toArray();
								$tableVD->delete(array('idReservation' => $idResa));
								### save logs
								$log = new Logs();
								$log->dateOperation = date('Y-m-d H:i:s');
								$log->idGestionnaire = $gestId;
								$log->operation = "BO suppression de valeurs dynamiques pour la réservation ".$idResa;
								$log->dataBefore = $vals;
								$log->dataAfter = array();
								$log->tableName = "valeurs_dynamiques";
								$log->idReservation = $idResa;
								$log->idLocataire = $resa->idLocataire;
								$this->getLogsTable()->saveLogs($log);
							}
							## suppression des ms
							$msRows = $tableSuivis->select(array('idResa' => $idResa));
							if($msRows->count() > 0) {
								$vals = $msRows->toArray();
								$tableSuivis->delete(array('idResa' => $idResa));
								### save logs
								$log = new Logs();
								$log->dateOperation = date('Y-m-d H:i:s');
								$log->idGestionnaire = $gestId;
								$log->operation = "BO suppression de suivis pour la réservation ".$idResa;
								$log->dataBefore = $vals;
								$log->dataAfter = array();
								$log->tableName = "suivis";
								$log->idReservation = $idResa;
								$log->idLocataire = $resa->idLocataire;
								$this->getLogsTable()->saveLogs($log);
							}
							$msRows = $tableSuivisVD->select(array('idResa' => $idResa));
							if($msRows->count() > 0) {
								$vals = $msRows->toArray();
								$tableSuivisVD->delete(array('idResa' => $idResa));
								### save logs
								$log = new Logs();
								$log->dateOperation = date('Y-m-d H:i:s');
								$log->idGestionnaire = $gestId;
								$log->operation = "BO suppression de valeurs dynamiques suivis pour la réservation ".$idResa;
								$log->dataBefore = $vals;
								$log->dataAfter = array();
								$log->tableName = "suivis_values";
								$log->idReservation = $idResa;
								$log->idLocataire = $resa->idLocataire;
								$this->getLogsTable()->saveLogs($log);
							}
							## suppression des documents
							$docsRows = $tableDocsResa->select(array('idReservation' => $idResa));
							if($docsRows->count() > 0) {
								foreach($docsRows as $d) {
									$idDocument = $d->idDocument;
									$doc = $tableDocs->select(array('id' => $idDocument))->current();
									if($doc) {
										$tableDocs->delete(array('id' => $idDocument));
										### save logs
										$log = new Logs();
										$log->dateOperation = date('Y-m-d H:i:s');
										$log->idGestionnaire = $gestId;
										$log->operation = "BO suppression document pour la réservation ".$idResa;
										$log->dataBefore = $doc;
										$log->dataAfter = array();
										$log->tableName = "documents";
										$log->idReservation = $idResa;
										$log->idLocataire = $resa->idLocataire;
										$this->getLogsTable()->saveLogs($log);
									}
								}
								$tableDocsResa->delete(array('idReservation' => $idResa));
							}

						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception msg=".$ex->getMessage());
						}
					} else {
						if ($msg == "") {
							$msgParResa = "- Erreur suppression réservation($idResa)<br>";
							$msg .= $msgParResa;
						}
						$etatSuppression['ko'] = true;
						$idsNonSuppimer[$idResa] = array(
										'idResa' => $idResa,
										'nomLocataire' => $resa->nomLocataire,
										'prenomLocataire' => $resa->prenomLocataire,
										'numeroChambre' => $resa->numeroChambre,
										'erreur' => $msgParResa);
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa msg=$msg");
				}
			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");
				$msg = "- Pas une réservation";
			}
			$success	= ($msg != '');


			$msgCss = "alert-success";
			if (array_key_exists('ok', $etatSuppression) && array_key_exists('ko', $etatSuppression)) {
				$msgCss = "alert-warning";
			} elseif (array_key_exists('ko', $etatSuppression) && !array_key_exists('ok', $etatSuppression)) {
				$msgCss = "alert-danger";
			}

			$csv = false;
			if ($listeCSV != "" && !empty($idsNonSuppimer)) {
				//générer la liste des demandes non archive au format csv
				$session->idsNonSupprimer = $idsNonSuppimer;
				$csv = true;
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : success=$success msg=$msg");
			$view = new JsonModel(array(
				'success' => $success,
						  'msg' => $msg,
						  'idsSupprimer' => $idsSupprimer,
						  'msgCss' => $msgCss,
						  'csv' => $csv,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	## EDITION GROUPEE

	public function editiongroupeeAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$htmlOutput = "";
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$isResa = $request->getPost('isResa');
			$mode = $request->getPost('mode');
			$idTypeSuivis = $request->getPost('idTypeSuivis');
			$idTypeCatalogue = $request->getPost('idTypeCatalogue');
			$idsResaPresta = $request->getPost('idsResaPresta', array());
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa mode=$mode ids=".json_encode($ids));

			/*$champs1 = $this->getThemeFields(1);
			$champs2 = $this->getThemeFields(2);
			$champs3 = $this->getThemeFields(3);

			$champs = array();

			$rows = $this->getTableObjet('champs_de_base')->select();
			foreach ($rows as $row) {
				$champs[$row->equivalentSql] = $row;
			}

			$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
			foreach ($champsDynamiques as $row) {
				$champs[$row->equivalentSql] = $row;
			}*/

			$params = array();
			if ($idTypeSuivis) {
				$params['idTypeSuivis'] = $idTypeSuivis;
			}
			if ($idTypeCatalogue) {
				$params['idTypeCatalogue'] = $idTypeCatalogue;
			}

			$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			/*$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>$mode,'modeEmploi'=>'editionGroupe'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>$mode,'modeEmploi'=>'editionGroupe'));
			$allChamps = $this->translateChamps($allChampsResult);
			$champsSource = $this->getChampCatTable()->getAllChamps(array('mode'=>$mode,'modeEmploi'=>'editionGroupe','typeRetour'=>'sourceChamps'));
			//recup des equivalentSql des champs de base
			$champsEquivalentSql = $this->getChampCatTable()->getAllChamps(array('mode'=>$mode,'modeEmploi'=>'editionGroupe','typeRetour'=>'equivalentSql'));

			//$champs = $this->getFieldsListe($mode,$params);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keys_champs=".json_encode(array_keys($catRows)));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champs=".json_encode($catRows));*/

			$categoriesResident = array();
			$documentsResidentParCat = array();

			$modedp = $isResa ? false : true;
			$rows = $this->getCategoriesResident(true, $modedp);
			$categoriesResident = $rows;

			$options = array('idProfile' => $idProfile, 'gestId' => $gestId, 'typeRetourChamps' => 'avecChamps', 'mode' => $mode, 'modeEmploi' => 'editionGroupe');
			$optionsSelectHtml = $this->getChampCatTable()->getChampsTreeSelectOptionsHtml($options);


			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/editiongroupee')
				->setVariables(array(
					//'catRows'=>$catRows,
					'isResa' => $isResa,
					'ids' => $ids,
					'mode' => $mode,
					//'allChamps'=>$allChamps,
					//'champsSource'=>$champsSource,
					//'champsEquivalentSql'=>$champsEquivalentSql,
					'idsResaPresta' => $idsResaPresta,
					'categoriesResident' => $categoriesResident,
					'optionsSelectHtml' => $optionsSelectHtml,
				));

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
						  'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function updateDataSql($table, $data, $ids, $mode = "reservation", $idsResaPresta = array())
	{
		$tableObj = $this->getTableObjet($table);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$erreurs = array();

		//$select->where(array(new Predicate\In('programme_campagne.idCampagne',$ids)));
		if ($table == "reservations") {
			$rows = $tableObj->select(array(new Predicate\In('reservations.id', $ids)));
			foreach ($rows as $resa) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($resa, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update reservation(edition groupé) : ".$resa->id;
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "reservations";
				$log->idReservation = $resa->id;
				$log->idLocataire = $resa->idLocataire;
				$this->getLogsTable()->saveLogs($log);

				### controle changement dates arrivée et départ
				// on verifie la disponibilite de date arrivée
				if (array_key_exists('dateArrivee', $data) && $data['dateArrivee'] != "" && $data['dateArrivee'] != $resa->dateArrivee) {
					$isOccupe = $this->getResaTable()->checkStartDate($data['dateArrivee'], $resa->idLogement, $resa->id, array(2, 3, 7, 15));//false => dispo
					$isDispo = $this->checkDisponibiliteLogementBredea($resa->id, $data['dateArrivee']);
					$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $data['dateArrivee'], $resa->dateDepart);
					if (!$isDispo || $isOccupe || $bloquerCSMsg != '') {
						unset($data['dateArrivee']);
						if ($bloquerCSMsg != '') {
							$erreurs[] = "Logement $resa->numeroChambre non disponible pour la nouvelle date arrivée : ". $bloquerCSMsg;
						} else {
							$erreurs[] = "Logement $resa->numeroChambre non disponible pour la nouvelle date arrivée";
						}
					}
				}

				// on verifie la disponibilite de date de depart
				if (array_key_exists('dateDepart', $data) && $data['dateDepart'] != "" && $data['dateDepart'] != $resa->dateDepart) {
					$isOccupe = $this->getResaTable()->checkEndDate($data['dateDepart'], $resa->idLogement, $resa->id, array(2, 3, 7, 15));//false => dispo
					$isDispo = $this->checkDisponibiliteLogementBredea($resa->id, $data['dateDepart']);
					$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $resa->dateArrivee, $data['dateDepart']);
					if (!$isDispo || $isOccupe || $bloquerCSMsg != '') {
						unset($data['dateDepart']);
						if ($bloquerCSMsg != '') {
							$erreurs[] = "Logement $resa->numeroChambre non disponible pour la nouvelle date départ : ". $bloquerCSMsg;
						} else {
							$erreurs[] = "Logement $resa->numeroChambre non disponible pour la nouvelle date départ";
						}
					}
				}
				### finc controle dates

				## verification dates facturation si changement dates arrivee ou depart
				## si on decale la date d arrive dans le passé, on decale aussi la date debut de facturation
				if (array_key_exists('dateArrivee', $data)) {
					if (strtotime($data['dateArrivee']) < strtotime($resa->dateArrivee)) {
						$tableObj->update(array('dateArriveeTheorique' => $data['dateArrivee']), array('id' => $resa->id));
					}
				}

				## si on decale la date de depart dans le future, on decale aussi la date fin facturation
				if (array_key_exists('dateDepart', $data)) {
					if (strtotime($data['dateDepart']) > strtotime($resa->dateDepart)) {
						// update date + changement de flags notification caf
						$tableObj->update(array('dateDepartTheorique' => $data['dateDepart'], 'cafChangementDateDepartTheorique' => '1'), array('id' => $resa->id));
					}
				}

				## maj mode paiement presta en virement si rib controller
				//verification si on a déjà les champs RIB rempli
				if (array_key_exists('statutRIB', $data)) {
					$msgCheck = $this->isRIBRempli($resa->id);
					if ($msgCheck == 'ok') {
						if ($data['statutRIB'] == 'controler') {
							$this->getPrestaTable()->majModePaiement($resa->id, 'Virement');
						}
					} else {
						$erreurs[] = $msgCheck;
						$tableObj->update(array('statutRIB' => null), array('id' => $resa->id));
					}
				}

				if (array_key_exists('idMenage', $data) && $resa->idMenage != $data['idMenage']) {
					$this->saveMenageHistorique($resa->id, $resa->idMenage, $data['idMenage']);
				}

				## Modification de l'etat de la résa en parti
				if (array_key_exists('dateDepart', $data)) {
					if (strtotime($data['dateDepart']) != strtotime($resa->dateDepart)) {
						$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if($modeCamp && $modeCamp->majEtatResaEnParti == 1) {
							if(strtotime($data['dateDepart']) <= strtotime(date('Y-m-d'))) {
								$tableObj->update(array('etat' => 6), array('id' => $resa->id));
							}
						}
					}
				}
			}
			if (!empty($data)) {
				$tableObj->update($data, array(new Predicate\In('reservations.id', $ids)));
			}
		} elseif ($table == "locataires") {
			foreach ($ids as $idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				if ($resa) {
					$loc = $tableObj->select(array('id' => $resa->idLocataire))->current();
					//save dans les logs
					$log = new Logs();
					$diff = $log->arrayDiff($loc, $data);
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO update usager(edition groupé) : ".$loc->nom.' '.$loc->prenom;
					$log->dataBefore = $diff['before'];
					$log->dataAfter = $diff['after'];
					$log->tableName = "locataires";
					$log->idReservation = $resa->id;
					$log->idLocataire = $resa->idLocataire;
					$this->getLogsTable()->saveLogs($log);

					$tableObj->update($data, array('id' => $resa->idLocataire));
				}
			}
		} elseif ($table == 'edl') {
			$rows = $tableObj->select(array(new Predicate\In('edl.id_reservations', $ids)));
			foreach ($rows as $edl) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($edl, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update edl(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "edl";
				$log->idReservation = $edl->id_reservations;
				$log->idLocataire = $edl->id_locataire;
				$this->getLogsTable()->saveLogs($log);
			}
			$tableObj->update($data, array(new Predicate\In('edl.id_reservations', $ids)));
		} elseif ($table == 'colis' && $mode == "colis") {
			$rows = $tableObj->select(array(new Predicate\In('colis.id', $ids)));
			foreach ($rows as $coli) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($coli, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update colis(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "colis";
				$log->idReservation = $coli->idResa;
				$this->getLogsTable()->saveLogs($log);
			}
			$tableObj->update($data, array(new Predicate\In('colis.id', $ids)));
		} elseif ($table == 'demandes' && $mode == "formulaire") {
			$rows = $tableObj->select(array(new Predicate\In('demandes.id', $ids)));
			foreach ($rows as $dem) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($dem, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update demandes(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "demandes";
				$log->idReservation = $dem->idResa;
				$this->getLogsTable()->saveLogs($log);
			}
			$tableObj->update($data, array(new Predicate\In('demandes.id', $ids)));
		} elseif ($table == 'plai_ressources') {
			$tableObj->update($data, array(new Predicate\In('plai_ressources.idResa', $ids)));

			$rowsResult = $tableObj->select(array(new Predicate\In('plai_ressources.idResa', $ids)));
			$idsResaExist = array();
			foreach ($rowsResult as $r) {
				$idsResaExist[] = $r->idResa;
			}
			foreach ($ids as $idResa) {
				if (!in_array($idResa, $idsResaExist)) {
					$data['idResa'] = $idResa;
					$tableObj->insert($data);
				}
			}
			$rows = $tableObj->select(array(new Predicate\In('plai_ressources.idResa', $ids)));
			foreach ($rows as $ress) {

				//maj des depassement
				$this->getPLAITable()->calculerEtMajDepassement($ress->id);
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($ress, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update ressources(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "plai_ressources";
				$log->idReservation = $ress->idResa;
				$this->getLogsTable()->saveLogs($log);
			}
		} elseif ($table == 'domiciliations' && $mode == "dp") {
			$rows = $tableObj->select(array(new Predicate\In('domiciliations.id', $ids)));
			foreach ($rows as $dp) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($dp, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update domiciliation(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "domiciliations";
				$log->idLocataire = $dp->idLocataire;
				$this->getLogsTable()->saveLogs($log);
			}
			$tableObj->update($data, array(new Predicate\In('domiciliations.id', $ids)));
		} elseif ($table == "prestations_to_resa" && !empty($idsResaPresta)) {
			if (array_key_exists('controle1', $data) || array_key_exists('controle2', $data) || array_key_exists('modePaiement', $data)) {
				$rows = $tableObj->select(array(new Predicate\In('prestations_to_resa.id', $idsResaPresta), 'prestations_to_resa.etatPrestation' => 'affecte'));
				foreach ($rows as $ptr) {
					$update = true;
					if ($ptr->etatPrestation != "affecte" && (!array_key_exists('modePaiement', $data) || array_key_exists('modePaiement', $data) && $ptr->etatPrestation == "regle")) {
						$erreurs[] = "Modification bloquée pour la résa $ptr->idReservation: La prestation est en état différent d'affectée";
					} else {
						if (array_key_exists('modePaiement', $data) && $data['modePaiement'] == 'Virement') {
							//si mode Virement, on verifie si le RIB est controlé
							$msgRIB = $this->getPrestaTable()->checkStatutRIB($ptr->idReservation);
							if ($msgRIB != 'ok') {
								$update = false;
								$erreurs[] = $msgRIB;
							}
						}
						if ($update) {
							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($ptr, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update etat controle prestation (edition groupé)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "prestations_to_resa";
							$log->idReservation = $ptr->idReservation;
							//$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###
							$tableObj->update($data, array('id' => $ptr->id));
						}
					}
				}
			}
		} elseif ($table == 'logements' && $mode == "logements") {
			$rows = $tableObj->select(array(new Predicate\In('logements.id', $ids)));
			foreach ($rows as $row) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($row, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update logements(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "logements";
				$log->idReservation = 0;
				$this->getLogsTable()->saveLogs($log);
			}
			$tableObj->update($data, array(new Predicate\In('logements.id', $ids)));
			## update PMS
			foreach($ids as $idLoge){
				$this->saveLogementPms($idLoge);
			}
		} elseif ($table == 'prelevements_sepa') {
			$tableObj->update($data, array(new Predicate\In('prelevements_sepa.idReservation', $ids)));

			$rowsResult = $tableObj->select(array(new Predicate\In('prelevements_sepa.idReservation', $ids)));
			$idsResaExist = array();
			foreach ($rowsResult as $r) {
				$idsResaExist[] = $r->idReservation;
			}
			foreach ($ids as $idResa) {
				if (!in_array($idResa, $idsResaExist)) {
					$data['idReservation'] = $idResa;
					$this->getSEPATable()->save($data);
				}
			}
			$rows = $tableObj->select(array(new Predicate\In('prelevements_sepa.idReservation', $ids)));
			foreach ($rows as $ress) {
				//save dans les logs
				$log = new Logs();
				$diff = $log->arrayDiff($ress, $data);
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO update SEPA(edition groupé)";
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "prelevements_sepa";
				$log->idReservation = $ress->idReservation;
				$this->getLogsTable()->saveLogs($log);
			}
		}
		return $erreurs;
	}

	private function copyLocatairesDocs($name, $ids, $newName = "")
	{
		$source = getcwd()."/public/docs/locataires/tmp/".$name;

		if (file_exists($source)) {
			foreach ($ids as $idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				if ($resa) {
					$idLocataire = $resa->idLocataire;
					if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
						mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
					}
					$destination = getcwd()."/public/docs/locataires/".$idLocataire."/".$name;
					if ($newName != "") {
						$destination = getcwd()."/public/docs/locataires/".$idLocataire."/".$newName;
					}

					copy($source, $destination);
				}
			}
			unlink($source);
		}
	}

	public function validereditiongroupeeAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}


		if ($request->isXmlHttpRequest()) {
			$tools = new Tools();
			$msg = "";
			$success = true;

			$champs = $request->getPost('champName');
			$ids = $request->getPost('idsToChange');
			$isResa = $request->getPost('isReservation');
			$mode = $request->getPost('mode');//mode, reservation, formulaire,colis...
			$tableSource = $request->getPost('tableSource');//pour champs_demandes, champs_colis, champs_formulaire
			$idsResaPresta = $request->getPost('idsResaPrestaToChange', array());
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : mode=$mode isResa=$isResa ids=".json_encode($ids)." champs=".json_encode($champs));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : POST=".json_encode($request->getPost()));

			$recalculerPresta = false;
			if ($champs) {
				foreach ($champs as $equivalentSql) {
					$valeur = $request->getPost($equivalentSql);
					$tableName = $request->getPost('tableName-'.$equivalentSql, '');
					$selectAddVal = $request->getPost($equivalentSql.'__chk',null);
					if(is_array($valeur)) $valeur = implode(',',array_unique($valeur));

					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champName=$equivalentSql valeur=$valeur");
					if ($mode == "logements") {

						## si champs de base demandes en premier
						$champ = $this->getTableObjet('champs_logements')->select(array('equivalentSql' => $equivalentSql, 'table' => 'logements'))->current();
						if ($champ) {
							if ($valeur && $champ->idTypeHtml == 2) {
								$valeur = date('Y-m-d', strtotime($valeur));
							}

							$champCommun = $this->getTableObjet('champs_formulaires_loge')->select(array('equivalentSql' => $equivalentSql, 'champCommun' => '1', 'active' => '1'))->current();
							if($champCommun){
								## on vérifie si le logement a des sous logements, si ou on les maj aussi
								foreach($ids as $idLoge){
									$sousLogements = $this->getLogementTable()->getSousLogements($idLoge);
									if(!empty($sousLogements)) {
										$idsLog = array_keys($sousLogements);
										$ids = array_merge($ids,$idsLog);
									}
								}
								$ids = array_unique($ids);
							}

							if ($champ->idTypeHtml == 8) {
								$valeur = $valeur ? '1' : '0';
							}
							//if($valeur){
							$data = array($equivalentSql => $valeur);

							$this->updateDataSql($champ->table, $data, $ids, $mode);

							//}
						}
					} elseif ($mode == "colis") {
						## Dans ce cas les ID sont des colisId
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($ids as $idColis) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champName=$equivalentSql idColis=$idColis");

							## Utilisation directe des methodes spécifiques de ColisController
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$colis		= new ColisController();
							$colis->setServiceLocator($this->getServiceLocator());
							$formFields	= $colis->getFormFields();
							$champ		= (array) $formFields['dynFields'][$equivalentSql];
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".json_encode($champ));

							if ($champ) {
								## Il s'agit d'un champs dynamique dans champs_colis
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($champ[idTypeHtml] == 2) {
									## Dernière bidouille pour les dates de champs_colis qui sont au format DD-MM-YYYY
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									list($dd, $mm, $yyyy)	= explode("-", $valeur);
									if ($yyyy > 1900) {
										$valeur	= "$yyyy-$mm-$dd";
									}
								}
								$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
								$success	= $colis->getColisTable()->updateColisDyn($adapter, $idColis, array($equivalentSql => $valeur));
							}
						}
					} elseif ($mode == "suivis") {
						$lienDoc = [];

						## Dans ce cas les ID sont des suivisId
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($ids as $idSuivis) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champName=$equivalentSql idSuivis=$idSuivis");


							## Utilisation directe des methodes spécifiques de SuivisController
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$suivis		= new MultisuivisController();
							$suivis->setServiceLocator($this->getServiceLocator());

							$suiviRow = $suivis->getSuivisTable()->getSuivis($idSuivis);

							// var_dump($suiviRow);die();
							if ($suiviRow) {
								$formFields	= $suivis->getFormFields(array(), $suiviRow->idTypeSuivis);
								$champ		= (array) $formFields['dynFields'][$equivalentSql];
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".json_encode($champ));

								if ($champ) {
									## Il s'agit d'un champs dynamique dans champs_suivis
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($champ[idTypeHtml] == 2) {
										## Dernière bidouille pour les dates de champs_suivis qui sont au format DD-MM-YYYY
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $valeur);
										if ($yyyy > 1900) {
											$valeur	= "$yyyy-$mm-$dd";
										}
									}
									if (strpos($champ['equivalentSql'], 'catalogues_') !== false && $valeur > 0) {
										//maj champs catalogue

										$idTypeCatalogue = str_replace('catalogues_', '', $champ['equivalentSql']);
										$this->getCatalogueTable()->insertCatalogueSuivis($valeur, $idSuivis);
										$success = true;
									} else {
										$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
										$success	= $suivis->getSuivisTable()->updateSuivisDyn($adapter, $idSuivis, array($equivalentSql => $valeur));
									}
								}

								$champSuivisT = $this->getTableObjet('champs_suivis')
								->select(array('id' => $champ['id']))->current();
								$idDpOrResa = $suiviRow->idDp != "" ? $suiviRow->idDp : $suiviRow->idResa;

								$tbNameActionConditions = 'actions_conditions_suivis';
								$tbNameActionJs = 'actions_js_suivis';

								$actionConditions = $this->getTableObjet($tbNameActionConditions)
								->select(array('idChamp' => $champ['id']))->current();

								if ($actionConditions) {
									$actionJs = $this->getTableObjet($tbNameActionJs)
									->select(array('id' => $actionConditions->idAction, 'idType' => 4))
									->current();
								}


								// générer le modèle de doc
								$generatePdfDoc = $request->getPost("generatePdfDoc");
								if ($generatePdfDoc == '1') {
									// echo "<pre>";
									// var_dump($actionJs);
									// echo "</pre>";
									// die();

									$optionsDoc = array('urlReturn' => 'ABSOLU', 'mode' => $mode, 'impressionEnLot' => true);
									$ldoc = $this->genererModeleDocument($idSuivis, "", $actionJs->idChampAttache, $optionsDoc);

									$ldoc = substr($ldoc, strpos($ldoc, 'docs'), strlen($ldoc));
									$lienDoc[] = array('id' => $idDpOrResa, 'idSuivis' => $idSuivis, 'mode' => $mode, 'lien' => getcwd().'/public/'.$ldoc);
								}
							} // end if suivis row
						}

						if (count($lienDoc) > 0) {
							$url = "";
							foreach ($lienDoc as $key => $value) {
								$url .= $value['lien'] . " ";
							}

							$cmdLine = "convert -density 300 $url ".getcwd()."/public/docs/allmodeledocs.pdf";

							// var_dump($cmdLine);
							// die();

							shell_exec($cmdLine);
						}
					} elseif ($mode == "catalogue") {
						## Dans ce cas les ID sont des catalogueId
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($ids as $idCatalogue) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champName=$equivalentSql idCatalogue=$idCatalogue");


							## Utilisation directe des methodes spécifiques de CatalogueController
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$catalogue		= new CatalogueController();
							$catalogue->setServiceLocator($this->getServiceLocator());

							$catalogueRow = $this->getCatalogueTable()->getCatalogue($idCatalogue);
							if ($catalogueRow) {
								$formFields	= $catalogue->getFormFields(array(), $catalogueRow->idTypeCatalogue);
								$champ		= (array) $formFields['dynFields'][$equivalentSql];
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".json_encode($champ));

								if ($champ) {
									## Il s'agit d'un champs dynamique dans champs_catalogue
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($champ[idTypeHtml] == 2) {
										## Dernière bidouille pour les dates de champs_catalogue qui sont au format DD-MM-YYYY
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $valeur);
										if ($yyyy > 1900) {
											$valeur	= "$yyyy-$mm-$dd";
										}
									}
									$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
									$success	= $this->getCatalogueTable()->updateCatalogueDyn($adapter, $idCatalogue, array($equivalentSql => $valeur));
								}
							}
						}
					} elseif ($mode == "formulaire") {
						## Dans ce cas les ID sont des idDemande
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

						## si champs de base demandes en premier
						$champ = $this->getTableObjet('champs')->select(array('equivalentSql' => $equivalentSql, 'table' => 'demandes'))->current();
						if ($champ) {
							$valeur = $request->getPost($equivalentSql);
							if ($valeur && $champ->idTypeHtml == 2) {
								$valeur = date('Y-m-d', strtotime($valeur));
							}
							if (!$valeur && $champ->idTypeHtml == 4) {
								//cas documents
								$equivalentSql = str_replace("doc_", "", $equivalentSql);
								$valeur = $request->getPost("doc_".$equivalentSql);

								//on copie du repertoire tmp vers le vrais rep
								if ($valeur) {
									$this->copyLocatairesDocs($valeur, $ids);
								}
							}
							if ($champ->idTypeHtml == 8) {
								$valeur = $valeur ? '1' : '0';
							}
							//if($valeur){
							$data = array($equivalentSql => $valeur);

							$this->updateDataSql($champ->table, $data, $ids, $mode);

							//}
						} else {
							foreach ($ids as $idDemande) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idDemande=$idDemande champName=$equivalentSql valeur=$valeur");
								## Utilisation directe des methodes spécifiques de DemandesController
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$demande	= new DemandesController();
								$demande->setServiceLocator($this->getServiceLocator());
								$formFields	= $demande->getFormFields();
								$champ		= (array) $formFields['dynFields'][$equivalentSql];
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idDemande=$idDemande champName=$equivalentSql valeur=$valeur champ=".json_encode($champ));

								if ($champ) {
									## Il s'agit d'un champs dynamique dans champs_demandes
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($champ[idTypeHtml] == 2) {
										## Dernière bidouille pour les dates de champs_demandes qui sont au format DD-MM-YYYY
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $valeur);
										if ($yyyy > 1900) {
											$valeur	= "$yyyy-$mm-$dd";
										}
									}
									$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
									$success	= $demande->getDemandesTable()->updateDemandeDyn($adapter, $idDemande, array($equivalentSql => $valeur));
								}
							}
						}
					} else {
						$champ = $this->getTableObjet('champs')->select(array('equivalentSql' => $equivalentSql))->current();
						if ($tableName) {
							$champ = $this->getTableObjet('champs')->select(array('equivalentSql' => $equivalentSql, 'table' => $tableName))->current();
						}

						if ($champ) {
							$valeur = $request->getPost($equivalentSql);
							if(is_array($valeur)) $valeur = implode(',',array_unique($valeur));

							if ($valeur && $champ->idTypeHtml == 2) {
								$valeur = date('Y-m-d', strtotime($valeur));
							}
							if (!$valeur && $champ->idTypeHtml == 4) {
								//cas documents
								$equivalentSql = str_replace("doc_", "", $equivalentSql);
								$valeur = $request->getPost("doc_".$equivalentSql);

								//on copie du repertoire tmp vers le vrais rep
								if ($valeur) {
									$this->copyLocatairesDocs($valeur, $ids);
								}
							}
							if ($champ->idTypeHtml == 8) {
								$valeur = $valeur ? '1' : '0';
							}
							if ($champ->idTypeHtml == 5 || $champ->idTypeHtml == 12) {
								$recalculerPresta = true;// on recalcule la presta que si on modifie un champ nombre ou monétaire
							}
							//if($valeur){
							$data = array($equivalentSql => $valeur);

							// Vérification sur le champ etatDp : si pas de motif OU pas de date de sortie => ne peut pas update etatDp à Terminé
							$champEtatDp = false;
							if ($champ->table == 'domiciliations' && $champ->equivalentSql == 'etat' && $champ->sourceListe == 'domiciliations_etat') {
								$champEtatDp = true;
								$valeurEtatDp = $this->getTableObjet('domiciliations_etat')->select(array('id' => $valeur))->current();
								if ($valeurEtatDp->nom == 'Terminé') {
									foreach ($ids as $key => $idDpUp) {
										$dpUp = $this->getTableObjet('domiciliations')->select(array('id' => $idDpUp))->current();
										if ($dpUp->idMotif > 0 && ($dpUp->dateSortie != '' || !empty($dpUp->dateSortie))) {
											$okEtatDp = true;
										} else {
											$okEtatDp = false;
											break;
										}
									}
								}
							}

							if ($mode != 'dp' || !$champEtatDp) {
								$erreurs = $this->updateDataSql($champ->table, $data, $ids, $mode, $idsResaPresta);
							} elseif ($mode == 'dp' && $champEtatDp) {
								if ($okEtatDp) {
									$erreurs = $this->updateDataSql($champ->table, $data, $ids, $mode, $idsResaPresta);
								} else {
									$msg = 'Etat DP à Terminé impossible si pas de motif ou pas de date de sortie';
								}
							}

							if ($equivalentSql == "idProgramme" || $equivalentSql == "idSousProgramme") {
								$erreurs = $this->updateDataSql("locataires", $data, $ids);
							}
							if (!empty($erreurs)) {
								$msg = implode('<br />', $erreurs);
							}
							//}
						} else {
							//on check si champ dynamique
							//$champ = $this->getChampsTable()->getRowByWhere(array('equivalentSql'=>$equivalentSql,'nature'=>'libre'));
							if ($tableSource == "champs_formulaires" || $tableSource == "champs_demandes" || $tableSource == "champs_colis" || strpos($equivalentSql, 'catalogues_') !== false) {
								$champ = $this->getTableObjet($tableSource)->select(array('equivalentSql' => $equivalentSql, 'nature' => 'libre'))->current();

								if (!$champ && strpos($equivalentSql, 'catalogues_') !== false) {
									$valeur = $request->getPost($equivalentSql);
									if ($valeur > 0) {
										foreach ($ids as $id) {
											if ($mode == 'reservation') {
												$this->getCatalogueTable()->insertCatalogueResa($valeur, $id);
											} elseif ($mode == 'dp') {
												$this->getCatalogueTable()->insertCatalogueDp($valeur, $id);
											}
										}
									}
								}



								$champStatutDoc = "";
								if (!$champ &&  substr($equivalentSql, -12) == '__statut_doc') {
									$champDoc = substr($equivalentSql, 0, (strlen($equivalentSql) - 12));
									$champ = $this->getTableObjet($tableSource)->select(array('equivalentSql' => $champDoc))->current();
									if ($champ) {
										$champ->idTypeHtml = 3;
										$champ->sourceListe = 'statut_docs';
										$champStatutDoc = $champ;
									}
								}

								$champFinValiditeDoc = "";
								if (!$champ &&  substr($equivalentSql, -18) == '__fin_validite_doc') {
									$champDoc = substr($equivalentSql, 0, (strlen($equivalentSql) - 18));
									$champ = $this->getTableObjet($tableSource)->select(array('equivalentSql' => $champDoc))->current();
									if ($champ) {
										$champ->idTypeHtml = 2;
										$champFinValiditeDoc = $champ;
									}
								}

								if ($champ) {
									$valeur = $request->getPost($equivalentSql);
									if(is_array($valeur)) $valeur = implode(',',array_unique($valeur));
									if (!$valeur && $champ->idType == 4) {
										//cas documents
										//$equivalentSql = str_replace("doc_", "", $equivalentSql);
										$valeur = $request->getPost("doc_".$equivalentSql);

										//on copie du repertoire tmp vers le vrais rep
										if ($valeur) {
											$this->copyLocatairesDocs($valeur, $ids);
										}
									}
									if ($champ->idType == 8) {
										$valeur = $valeur ? '1' : '0';
									}

									$lienDoc = [];
									if (isset($valeur) /*&& $valeur != ""*/) {
										$tableValSelect = $this->getTableObjet('valeurs_select');
										foreach ($ids as $id) {
											## si il s'agit d'un champs statut document on le maj
											if (($tableSource == "champs_formulaires" || $tableSource == "champs_dynamiques") && $mode != "formulaire" && $mode != "colis" && $mode != "dp") {
												$resa = $this->getResaTable()->getResa($id);
												if ($resa) {
													## on recup le champ de la bonne campagne
													$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
													$select = $champsFormulaireTable->getSql()->select();
													$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
													$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.equivalentSql' => $champ->equivalentSql));
													$champ2Camp = $champsFormulaireTable->selectWith($select)->current();
													if ($champ2Camp) {
														$champ = $champ2Camp;
													}

													## controle valeurs champ liste sur la bonne campagne
													if (is_numeric($champ->sourceListe) && $valeur) {
														$select = $tableValSelect->getSql()->select();
														$select->join('champs_formulaires', 'valeurs_select.idSelect = champs_formulaires.sourceListe', array('idChamp' => 'id', 'idFormulaire', 'sourceListe'));
														$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
														$select->where(
															array(
																			'formulaires.idCampagne' => $resa->idCampagne,
																			'champs_formulaires.equivalentSql' => $champ->equivalentSql,
																			'valeurs_select.id' => $valeur,
																			)
														);
														$rowID = $tableValSelect->selectWith($select)->current();
														if (!$rowID) {
															$msg .= "Elément de liste Invalide(pas sur la bonne campagne)<br />";
															continue;
														}
													}
													//on cherche
													$idLocataire = $resa->idLocataire;
													$where = array('idChamp' => $champ->id, 'idLocataire' => $idLocataire, 'idReservation' => $id);

													##verification RIB-IBAN
													if ($champ->idType == 15) {
														$isValidRIB = $tools->checkIBAN($valeur);
														if (!$isValidRIB) {
															$msg .= "IBAN $valeur Invalide<br />";
															continue;
														}
													}
													##verification RIB-BIC
													if ($champ->idType == 16) {
														$isValidBIC = $tools->checkBIC($valeur);
														if (!$isValidBIC) {
															$msg .= "BIC $valeur Invalide<br />";
															continue;
														}
													}

													##verification changement champ lié à une formule
													$rep = $this->getPrestaTable()->isPrestaDynField($resa->id, $champ->equivalentSql);
													if ($rep != "ok") {
														$msg .= "$rep<br />";
														continue;
													}

													##verification changement rib
													if ($champ->idType == 15 || $champ->idType == 16 || $champ->nomXML == 'rib_nomrib') {
														$this->checkMajStatutRIB($resa->id, $champ->id, $valeur);
													}

													//on check si existe =>update sinon insert
													$d = $this->getTableObjet('valeurs_dynamiques')->select($where)->current();
													if ($champStatutDoc) {
														if ($d) {
															$this->getTableObjet('valeurs_dynamiques')->update(array('statutDoc' => $valeur), $where);
														}
														/*else{
															$insert = array_merge($where,array('statutDoc'=>$valeur));
															$this->getTableObjet('valeurs_dynamiques')->insert($insert);
														}*/
													} elseif ($champFinValiditeDoc) {
														if ($d) {
															$this->getTableObjet('valeurs_dynamiques')->update(array('finValidite' => $valeur), $where);
														}
													} else {
														if ($d) {
															## si liste multiselect et que on coche Ajouter les vleurs, on écrase pas la valeur existant
															if($selectAddVal && $champ->idType == 18 && $d->valeur && $valeur){
																$newVals = explode(',',$valeur);
																$oldVals = explode(',',$d->valeur);
																if(!empty($newVals) && !empty($oldVals)){
																	$newValArr = array_filter(array_unique(array_merge($oldVals,$newVals)));
																	if(!empty($newValArr)) $valeur = implode(',',$newValArr);
																}
															}
															if($valeur =='0') $valeur = '';
															$this->getTableObjet('valeurs_dynamiques')->update(array('valeur' => $valeur), $where);
														} else {
															$insert = array_merge($where, array('valeur' => $valeur));
															$this->getTableObjet('valeurs_dynamiques')->insert($insert);
														}
													}

													## on enleve le champs des champs obligatoire vide, si rempli
													if($valeur && $resa){
														$tableChampsObligatoires = $this->getTableObjet('champs_obligatoires');
														$tableChampsObligatoires->delete(array('idResa'=>$resa->id,'idChamp'=>$champ->id));
													}


													### save logs
													$log = new Logs();
													$log->dateOperation = date('Y-m-d H:i:s');
													$log->idGestionnaire = $gestId;
													$log->operation = "BO update usager (edition groupé)";
													$log->dataBefore = $d ? array($champ->equivalentSql => $d->valeur) : array();
													$log->dataAfter = array($champ->equivalentSql => $valeur);
													$log->tableName = "champs_formulaires";
													$log->idReservation = $resa->id;
													$log->idLocataire = $resa->idLocataire;
													$this->getLogsTable()->saveLogs($log);
													###
												}
											} elseif ($tableSource == "champs_demandes" && $mode == "formulaire") {
												$dem = $this->getTableObjet('demandes')->select(array('id' => $id))->current();
												if ($dem) {
													$where = array('idChamp' => $champ->id, 'idDemande' => $dem->id);
													//on check si existe =>update sinon insert
													$d = $this->getTableObjet('demandes_values')->select($where)->current();
													if ($d) {
														## si liste multiselect et que on coche Ajouter les vleurs, on écrase pas la valeur existant
														if($selectAddVal && $champ->idType == 18 && $d->valeur && $valeur){
															$newVals = explode(',',$valeur);
															$oldVals = explode(',',$d->valeur);
															if(!empty($newVals) && !empty($oldVals)){
																$newValArr = array_filter(array_unique(array_merge($oldVals,$newVals)));
																if(!empty($newValArr)) $valeur = implode(',',$newValArr);
															}
														}
														if($valeur =='0') $valeur = '';
														$this->getTableObjet('demandes_values')->update(array('valeur' => $valeur), $where);
													} else {
														$insert = array_merge($where, array('valeur' => $valeur));
														$this->getTableObjet('demandes_values')->insert($insert);
													}
													### save logs
													$log = new Logs();
													$log->dateOperation = date('Y-m-d H:i:s');
													$log->idGestionnaire = $gestId;
													$log->operation = "BO update demande (edition groupé)";
													$log->dataBefore = $d ? array($champ->equivalentSql => $d->valeur) : array();
													$log->dataAfter = array($champ->equivalentSql => $valeur);
													$log->tableName = "champs_demandes";
													$log->idReservation = $dem->idResa;
													$log->idLocataire = $dem->idLocataire;
													$this->getLogsTable()->saveLogs($log);
													###
												}
											} elseif ($tableSource == "champs_colis" && $mode == "colis") {
												$col = $this->getTableObjet('colis')->select(array('id' => $id))->current();
												if ($col) {
													$where = array('idChamp' => $champ->id, 'idColis' => $col->id);
													//on check si existe =>update sinon insert
													$d = $this->getTableObjet('colis_values')->select($where)->current();
													if ($d) {
														## si liste multiselect et que on coche Ajouter les vleurs, on écrase pas la valeur existant
														if($selectAddVal && $champ->idType == 18 && $d->valeur && $valeur){
															$newVals = explode(',',$valeur);
															$oldVals = explode(',',$d->valeur);
															if(!empty($newVals) && !empty($oldVals)){
																$newValArr = array_filter(array_unique(array_merge($oldVals,$newVals)));
																if(!empty($newValArr)) $valeur = implode(',',$newValArr);
															}
														}
														if($valeur =='0') $valeur = '';
														$this->getTableObjet('colis_values')->update(array('valeur' => $valeur), $where);
													} else {
														$insert = array_merge($where, array('valeur' => $valeur));
														$this->getTableObjet('colis_values')->insert($insert);
													}
													### save logs
													$log = new Logs();
													$log->dateOperation = date('Y-m-d H:i:s');
													$log->idGestionnaire = $gestId;
													$log->operation = "BO update colis (edition groupé)";
													$log->dataBefore = $d ? array($champ->equivalentSql => $d->valeur) : array();
													$log->dataAfter = array($champ->equivalentSql => $valeur);
													$log->tableName = "champs_colis";
													$log->idReservation = $col->idResa;
													$this->getLogsTable()->saveLogs($log);
													###
												}
											} elseif ($tableSource == "champs_formulaires" && $mode == "dp") {
												//$dp = $this->getTableObjet('domiciliations')->select(array('id'=>$id))->current();
												$dp = $this->getDomiciliationsTable()->getDomiciliationById($id);
												if ($dp) {

													## on recup le champ de la bonne campagne
													$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
													$select = $champsFormulaireTable->getSql()->select();
													$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
													$select->where(array('formulaires.idCampagne' => $dp->idCampagne, 'champs_formulaires.equivalentSql' => $champ->equivalentSql));
													$champ2Camp = $champsFormulaireTable->selectWith($select)->current();
													if ($champ2Camp) {
														$champ = $champ2Camp;
													}

													## controle valeurs champ liste sur la bonne campagne
													if (is_numeric($champ->sourceListe) && $valeur) {
														$select = $tableValSelect->getSql()->select();
														$select->join('champs_formulaires', 'valeurs_select.idSelect = champs_formulaires.sourceListe', array('idChamp' => 'id', 'idFormulaire', 'sourceListe'));
														$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
														$select->where(
															array(
																			'formulaires.idCampagne' => $dp->idCampagne,
																			'champs_formulaires.equivalentSql' => $champ->equivalentSql,
																			'valeurs_select.id' => $valeur,
																			)
														);
														$rowID = $tableValSelect->selectWith($select)->current();
														if (!$rowID) {
															$msg .= "Elément de liste Invalide(pas sur la bonne campagne)<br />";
															continue;
														}
													}
													//on cherche
													$idLocataire = $dp->idLocataire;
													$where = array('idChamp' => $champ->id, 'idLocataire' => $idLocataire, 'idDp' => $id);

													//on check si existe =>update sinon insert
													$d = $this->getTableObjet('valeurs_dynamiques')->select($where)->current();
													if ($d) {
														## si liste multiselect et que on coche Ajouter les vleurs, on écrase pas la valeur existant
														if($selectAddVal && $champ->idType == 18 && $d->valeur && $valeur){
															$newVals = explode(',',$valeur);
															$oldVals = explode(',',$d->valeur);
															if(!empty($newVals) && !empty($oldVals)){
																$newValArr = array_filter(array_unique(array_merge($oldVals,$newVals)));
																if(!empty($newValArr)) $valeur = implode(',',$newValArr);
															}
														}
														if($valeur =='0') $valeur = '';
														$this->getTableObjet('valeurs_dynamiques')->update(array('valeur' => $valeur), $where);
													} else {
														$insert = array_merge($where, array('valeur' => $valeur));
														$this->getTableObjet('valeurs_dynamiques')->insert($insert);
													}

													### save logs
													$log = new Logs();
													$log->dateOperation = date('Y-m-d H:i:s');
													$log->idGestionnaire = $gestId;
													$log->operation = "BO update usager (edition groupé DP)";
													$log->dataBefore = $d ? array($champ->equivalentSql => $d->valeur) : array();
													$log->dataAfter = array($champ->equivalentSql => $valeur);
													$log->tableName = "champs_formulaires";
													$log->idReservation = 0;
													$log->idLocataire = $dp->idLocataire;
													$this->getLogsTable()->saveLogs($log);
													###
												}
											}

											// on vérifie si on a des actions dessus
											// if is suivis then change table name
											$tbNameActionConditions = 'actions_conditions';
											$tbNameActionJs = 'actions_js';

											$actionConditions = $this->getTableObjet($tbNameActionConditions)
											->select(array('idChamp' => $champ->id, 'valeurExact' => $valeur))->current();
											if ($actionConditions) {
												$actionJs = $this->getTableObjet($tbNameActionJs)
													->select(array('id' => $actionConditions->idAction, 'idType' => 4))
													->current();
												if ($actionJs) {
													// générer le modèle de doc
													// $idResa,$noFacture, $idModele, $options
													$optionsDoc = array('mode' => $mode);
													$ldoc = $this->genererModeleDocument($id, "", $actionJs->idChampAttache, $optionsDoc);
													$ldoc = substr($ldoc, strpos($ldoc, 'docs'), strlen($ldoc));
													$lienDoc[] = array('id' => $id, 'mode' => $mode, 'lien' => getcwd().'/public/'.$ldoc);
												}
											}
										}//end foreach
									}

									if (count($lienDoc) > 0) {
										$url = "";
										foreach ($lienDoc as $key => $value) {
											$url .= $value['lien'] . " ";
										}
										$cmdLine = "convert -density 300 $url ".getcwd()."/public/docs/allmodeledocs.pdf";
										shell_exec($cmdLine);
									}

									if ($mode == 'dp') {
										$dp = $this->getTableObjet('domiciliations')->select(array('id' => $id))->current();
										$idCampagne = $dp->idCampagne;
									} else {
										$resa = $this->getResaTable()->getResa($id);
										$idCampagne = $resa->idCampagne;
									}
								}
							} else {
								if ($equivalentSql == 'intercontrat') {
									$idEtat = $request->getPost($equivalentSql);
									$duree = $request->getPost('dureeIntercontrat');
									if ($idEtat && $duree > 0) {
										//on maj que les etat avec valide 0 de la table intercontrat
										foreach ($ids as $id) {
											$ic = $this->getTableObjet('intercontrat')->select(array('idReservation' => $id, 'idEtat' => $idEtat, 'valide' => '0'))->current();
											if ($ic) {
												$this->getTableObjet('intercontrat')->update(array('duree' => $duree), array('id' => $ic->id));
											}
										}
									}
								}
							}
						}
						if ($mode == "reservation") {
							## MAJ BREDEA
							foreach ($ids as $id) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$id");
								$this->updateResaPmsAndSig($id);

								## recalculation des prestation calculé
								//$recalculerPresta = true;
								if ($recalculerPresta) {
									$this->getPrestaTable()->calculerPrestationsDeResa($id);
								}
							}
						} elseif ($mode == 'dp') {
							foreach ($ids as $id) {
								$dp = $this->getTableObjet('domiciliations')->select(array('id' => $id))->current();
								$resaDeLocDp = $this->getResaTable()->getLocLastResa($dp->idLocataire);
								if ($resaDeLocDp) {
									$this->updateResaPmsAndSig($resaDeLocDp->id);
								}
							}
						}
					}
				}
				if ($msg == "") {
					$msg = 'Validation bien faite, la liste sera actualisee';
				} else {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ids=".json_encode($ids)." msg=$msg");
					$success = false;
				}
			} elseif (!$champs) {
				$msg = "Veuillez choisir un champ, et fournir une valeur";
				$success = false;
			}


			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'lienDoc' => $lienDoc,
						'idCampagne' => $idCampagne,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadchampAction()
	{
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$champ = $request->getPost('champ');
			$source = $request->getPost('source');
			$code = $request->getPost('code');
			if($code == 'allFields' && is_numeric($champ)) {
				$idForm = $champ;
				$htmlOP = '';
				if($source == 'champs_formulaires') {
					$htmlOP = '<div class="col-sm-12 red margin-bottom-15"><label>Veuillez remplir tout les champs ou enlever les champs à ne pas modifier pour ne pas écraser des valeurs existante</label></div>';
					$champsNonModifiables = array('age', 'nom', 'prenom', 'dateNaissance', 'idLogement', 'numeroChambre');
					$tableCF = $this->getTableObjet('champs_formulaires');
					$select	= $tableCF->getSql()->select();
					$select->where(array('idFormulaire' => $idForm, 'active' => '1'));
					$select->order(array('row', 'column'));
					$rows = $tableCF->selectWith($select);
					foreach($rows as $row) {
						if(in_array($row->equivalentSql, $champsNonModifiables) || $row->idChampSuivis > 0 || in_array($row->idType, array('13', '19', '21'))) {
							continue;
						}
						$ret = $this->getInput($row->equivalentSql, 1, 1, null, array('source' => $source, 'allFields' => true));
						if($ret) {
							$htmlOP .= '<div class="col-sm-4">';
							$htmlOP .= '<label>'.$row->libelle.' <i class="fa fa-times red link eg-deleteField" title="Enlever ce champ"></i></label>';
							$htmlOP .= $ret;
							$htmlOP .= '</div>';
						}
					}
				}
			} else {
				$htmlOP = $this->getInput($champ, 1, 1, null, array('source' => $source, 'code' => $code));
			}

			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function createDemandeStatus($name, $value)
	{
		$html = null;
		$table = $this->getTableObjet('demandes_etat');
		$select = $table->getSql()->select();
		$rows = $table->selectWith($select);
		$html .= '<select class="form-control editable-input" name="'.$name.'">';
		foreach ($rows as $row) {
			$html .= '<option value="'.$row->id.'" '.($row->id == $value ? "selected" : "").'>'.$row->nom.'</option>';
		}
		$html .= '</select>';
		return $html;
	}

	private function createDemandeAffectation($name, $value)
	{
		$html = null;
		$rows = $this->getUserTable()->fetchByTech();
		$html .= '<select class="form-control editable-input" name="'.$name.'">';
		foreach ($rows as $row) {
			$html .= '<option value="'.$row->id.'" '.($row->id == $value ? "selected" : "").'>'.$row->display_name.'</option>';
		}
		$html .= '</select>';
		return $html;
	}

	private function getInput($champ, $colonne = 1, $ligne = 1, $valeur = null, $options = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=$champ valeur=$valeur options=".json_encode($options));

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$validerFichier = !empty($options['validerFichier']) ? true : false;//on ajoute un btn valider après upload du fichier
		$idResa = !empty($options['idResa']) ? $options['idResa'] : 0;
		$idDp = !empty($options['idDp']) ? $options['idDp'] : 0;
		//option source pour les champs demandes et colis
		$source = !empty($options['source']) ? $options['source'] : '';
		$code = !empty($options['code']) ? $options['code'] : '';
		$modeEditionInline = !empty($options['modeEditionInline']) ? $options['modeEditionInline'] : '';
		$allFields = !empty($options['allFields']) ? $options['allFields'] : false;//mod edition groupé avec affichage des champs par form
		$htmlOP = '<div class="form-group">';
		##Structure des names des input : champ-ligne-colonne
		$name = $champ;
		$idCampagne = null;
		$idResidenceUser = null;
		if ($idResa) {
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if ($resa) {
				$idCampagne = $resa->idCampagne;
				if ($resa->idLogement) {
					$resid = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
					if ($resid) {
						$idResidenceUser = $resid->idLogement;
					}
				} elseif ($resa->residenceOrientation) {
					$idResidenceUser = $resa->residenceOrientation;
				}
			}
		} elseif ($idDp) {
			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
			if ($dp) {
				$idCampagne = $dp->idCampagne;
			}
		}

		#champ cache pour stocker le name du champ, pour la modification
		$htmlOP .= '<input type="hidden" name="champName[]" value="'.$champ.'" />';

		$tChamps = $this->getTableObjet('champs');
		$row = $tChamps->select(array('code' => $code))->current();
		if (!$row) {
			$row = $tChamps->select(array('equivalentSql' => $champ))->current();
		}

		if ($source == "champs_logements") {
			$row = $this->getTableObjet($source)->select(array('equivalentSql' => $champ, 'table' => 'logements'))->current();
		}
		$options = array();
		$tableSource = "";
		if ($row) {
			## Traitement cas champs choix de résidence(residence1, residence2 etc)
			if(substr($row->code, 0, -1) == 'residence') {
				$row->table = 'residences';
				$row->equivalentSql = 'idResidence';
				$row->sourceListe = 'residences';
			}
			$usersDeleted = array();
			$tableSource = $row->table;
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=$champ valeur=$valeur sourceListe=".$row->sourceListe." typeHtml=".$row->idTypeHtml);
			if ($row->sourceListe) {
				if ($champ == 'affectedTo') {
					$tbl = $this->getTableObjet($row->sourceListe);
					$select = $tbl->getSql()->select();
					$select->join('user_role_linker', 'user.user_id = user_role_linker.user_id', array('user_id'));
					$select->join('user_role', 'user_role_linker.role_id = user_role.role_id');
					$select->where(array('user_role.isTech' => 1));
					$rows = $tbl->selectWith($select);
				} elseif ($champ == 'idUser') {
					//on recup le critere d affichage dans champs_de_base
					$rows = array();
					$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql' => 'idUser'))->current();
					if ($cb && $cb->critere) {
						$codeTypeArr = json_decode($cb->critere, true);
						if (!empty($codeTypeArr['codeType'])) {
							$rows = $this->getUserTable()->getUsersListeByCodeType($codeTypeArr['codeType'], $idCampagne, $idResidenceUser);
							$usersDeleted = $this->getUserTable()->getUsersDeletedByCodeType($codeTypeArr['codeType'], $idCampagne, $idResidenceUser);
						}
					}
				} elseif ($row->sourceListe == 'residences') {
					$rows =  $this->getResidencesTable()->fetchByGest($gestId, $all = true);
				} else {
					$rows = $this->getTableObjet($row->sourceListe)->select();
				}

				$sourceListe = $row->sourceListe;
				$optionHtml = "";
				foreach ($rows as $cle => $row) {
					if ($champ == 'idPays') {
						$options[$row->id] = $row->pays;
					} elseif ($champ == 'idNationalite') {
						$options[$row->id] = $row->nationalite;
					} elseif ($champ == 'langue') {
						$row->id = $row->codeISO;
						$options[$row->id] = $row->nom;
					} elseif ($champ == 'affectedTo') {
						$row->id = $row->user_id;
						$options[$row->id] = $row->username;
					} elseif ($champ == 'idUser') {
						$options[$cle] = $row;
					} elseif ($champ == 'idTypeBail') {
						$options[$row->id] = $row->typeBail;
					} elseif ($champ == 'idTypeBien') {
						$options[$row->id] = $row->typeBien;
					} else {
						$options[$row->id] = $row->nom;
					}
					$idValeur = $row->id;
					$extraOptions = "";
					if ($champ == 'idUser') {
						$idValeur = $cle;
						if (array_key_exists($idValeur, $usersDeleted)) {
							if ($valeur && $valeur == $idValeur) {
								//$extraOptions = 'disabled="disabled"';
							} else {
								continue;
							}
						}
					}

					if ($options[$idValeur] == $valeur) {
						$optionHtml .= '<option selected="selected" '.$extraOptions.' value="'.$idValeur.'">'.$options[$idValeur].'</option>';
					} else {
						$optionHtml .= '<option '.$extraOptions.' value="'.$idValeur.'">'.$options[$idValeur].'</option>';
					}
				}

				$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
				if($allFields) {
					$htmlOP .= '<option value="">Choisissez</option>';
				}
				if ($sourceListe == "statut_docs") {
					$htmlOP .= '<option value="">Choisissez</option>';
					$htmlOP .= '<option value="0">Non traitée</option>';
				}
				$htmlOP .= $optionHtml;
				$htmlOP .= '</select>';
			} elseif ($row->idTypeHtml == "2") {
				## type date
				//if($valeur == "0000-00-00") $valeur = date('d-m-Y');
				//$valeur = $valeur ? date('d-m-Y',strtotime($valeur)) : date('d-m-Y');
				if ($valeur == "0000-00-00") {
					$valeur = '';
				}
				if ($valeur) {
					$valeur = date('d-m-Y', strtotime($valeur));
				}

				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
						->setTemplate('reservation/liste/dateinput')
						->setVariables(array(
							  'name' => $name,
							  'value' => $valeur,
							  'plage' => $this->getPlageDeDate($champObj->id),
							  'modeEditionInline' => $modeEditionInline,
						));

				$htmlOP .= $this->getServiceLocator()
						->get('viewrenderer')
						->render($htmlViewPart);
			} elseif ($row->idTypeHtml == "8") {
				## type checkbox
				$checked	= $valeur ? "checked" : "";
				$htmlOP .= '<input type="checkbox" class="editable-input" name="'.$name.'" '.$checked.' />';
			} elseif ($row->idTypeHtml == "4") {
				## Document
				$idLocataire = null;
				if ($idResa) {
					$res = $this->getResaTable()->getResa($idResa);
					$idLocataire = $res->idLocataire;
				}
				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
						->setTemplate('reservation/liste/fileinput')
						->setVariables(array(
							  'name' => $name,
							  'value' => $valeur,
							  'validerFichier' => $validerFichier,
							  'modeEditionInline' => $modeEditionInline,
							  'idLocataire' => $idLocataire,
							  'idResa' => $idResa,
							  'idDp' => $idDp,
						));

				$htmlOP .= $this->getServiceLocator()
						->get('viewrenderer')
						->render($htmlViewPart);
			} else {
				if ($name == "remise_des_cles") {
					// select default
					$edl = $this->getEdlTable()->getByResaId($idResa);
					$res = $this->getResaTable()->getResa($idResa);

					if ($edl && $edl->type == 'sortant' && trim($edl->etat) == 'terminer') {
						$remise_des_cles = $res->remise_des_cles;
						$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
						$htmlOP .= '<option value="attente" '.((trim($remise_des_cles) == 'attente') ? 'selected' : ''). '>Attente</option>';
						$htmlOP .= '<option value="remis" '.((trim($remise_des_cles) == 'remis') ? 'selected' : ''). '>Remis</option>';
						$htmlOP .= '<option value="coffre" '.((trim($remise_des_cles) == 'coffre') ? 'selected' : ''). '>Coffre</option>';
						$htmlOP .= '<option value="factures" '.((trim($remise_des_cles) == 'factures') ? 'selected' : ''). '>Factures</option>';
						$htmlOP .= '</select>';
					} else {
						$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
						$htmlOP .= '<option value="attente">Attente</option>';
						$htmlOP .= '<option value="remis">Remis</option>';
						$htmlOP .= '<option value="coffre">Coffre</option>';
						$htmlOP .= '<option value="factures">Factures</option>';
						$htmlOP .= '</select>';
					}
				} elseif ($champ == 'statutRIB') {
					$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
					$htmlOP .= '<option value="">Vide</option>';
					$htmlOP .= '<option value="modifier">Modifié</option>';
					$htmlOP .= '<option value="controler">Controlé</option>';
					$htmlOP .= '</select>';
				} elseif ($champ == 'controle1' || $champ == 'controle2') {
					$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
					$htmlOP .= '<option value="">Vide</option>';
					$htmlOP .= '<option value="Non">Non</option>';
					$htmlOP .= '<option value="Oui">Oui</option>';
					$htmlOP .= '</select>';
				} elseif ($champ == "modePaiement") {
					$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
					$htmlOP .= '<option value="">Vide</option>';
					$htmlOP .= '<option value="Virement">Virement</option>';
					$htmlOP .= '<option value="Ticket">Ticket</option>';
					$htmlOP .= '</select>';
				} else {
					$htmlOP .= '<input type="text" class="form-control editable-input" name="'.$name.'" value="'.$valeur.'" />';
				}
			}
		} else {
			##champ dynamique
			$dynamique = $this->getChampdynamiqueTable()->getChampByName($champ);

			if ($dynamique || $source == "champs_demandes" || $source == "champs_colis" || $source == "champs_suivis" || $source == "champs_catalogue" || $source == "champs_dynamiques" || strpos($champ, 'catalogues_') !== false) {
				if ($source != "champs_demandes" && $source != "champs_colis" && $source != "champs_suivis" && $source != 'champs_catalogue') {
					$source = 'champs_formulaires';
				}
				if (strpos($champ, 'catalogues_') !== false) {
					$champObjResult = $this->getTableObjet($source)->select(array('equivalentSql' => $champ));
					$champObj = $champObjResult->current();
					if ($idCampagne) {
						## on recup le champ de la bonne campagne
						$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
						$select = $champsFormulaireTable->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where(array('formulaires.idCampagne' => $idCampagne, 'champs_formulaires.equivalentSql' => $champ));
						$champ2Camp = $champsFormulaireTable->selectWith($select);
						if ($champ2Camp) {
							$champObjResult = $champ2Camp;
							$champObj = $champ2Camp->current();
						}
					}
				} else {
					$champObjResult = $this->getTableObjet($source)->select(array('equivalentSql' => $champ, 'nature' => 'libre'));
					$champObj = $champObjResult->current();
					if ($idCampagne) {
						## on recup le champ de la bonne campagne
						$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
						$select = $champsFormulaireTable->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where(array('formulaires.idCampagne' => $idCampagne, 'champs_formulaires.equivalentSql' => $champ, 'nature' => 'libre'));
						$champ2Camp = $champsFormulaireTable->selectWith($select);
						if ($champ2Camp) {
							$champObjResult = $champ2Camp;
							$champObj = $champ2Camp->current();
						}
					}
				}

				## on vérifie si c'est un champ statut document avec sufix __statut_doc
				if (!$champObj &&  substr($champ, -12) == '__statut_doc') {
					$champDoc = substr($champ, 0, (strlen($champ) - 12));
					$champObj = $this->getTableObjet($source)->select(array('equivalentSql' => $champDoc, 'nature' => 'libre'))->current();
					if ($champObj) {
						$champObj->idType = 3;
						$champObj->sourceListe = 'statut_docs';
					}
				}

				## on vérifie si c'est un champ statut document avec sufix __fin_validite_doc
				if (!$champObj &&  substr($champ, -18) == '__fin_validite_doc') {
					$champDoc = substr($champ, 0, (strlen($champ) - 18));
					$champObj = $this->getTableObjet($source)->select(array('equivalentSql' => $champDoc, 'nature' => 'libre'))->current();
					if ($champObj) {
						$champObj->idType = 2;
					}
				}

				$type = $this->getTableObjet('type_champs_formulaire')->select(array('id' => $champObj->idType))->current();

				if (strpos($champObj->equivalentSql, 'catalogues_') !== false) {
					$optionHtml = "";
					$idTypeCatalogue = str_replace('catalogues_', '', $champObj->equivalentSql);
					$rows = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue);

					foreach ($rows as $id => $val) {
						$options[$id] = $val;

						if (trim($val) == trim($valeur)) {
							$optionHtml .= '<option selected="selected" value="'.$id.'">'.$options[$id].'</option>';
						} else {
							$optionHtml .= '<option value="'.$id.'">'.$options[$id].'</option>';
						}
					}

					$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
					if($allFields) {
						$htmlOP .= '<option value="">Choisissez</option>';
					}
					$htmlOP .= $optionHtml;
					$htmlOP .= '</select>';
				} elseif (is_numeric($champObj->sourceListe)) {
					//$rows = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champObj->sourceListe));
					## si on a d'autres champs avec le meme name, on recup leur listes
					$sourceListes = array();
					if ($champObjResult->count() >= 1) {
						foreach ($champObjResult as $chr) {
							if(is_numeric($chr->sourceListe)) $sourceListes[$chr->sourceListe] = $chr->sourceListe;
						}
					}

					if (count($sourceListes) <= 0) {
						$sourceListes[$champObj->sourceListe] = $champObj->sourceListe;
					}

					$optionHtml = "";
					foreach ($sourceListes as $sourceListe) {
						$rows = $this->getSelectOptions($sourceListe);
						foreach ($rows as $row) {
							$options[$row->id] = $row->valeur;

							$disabledOption	= ($champ == 'libre_statut_cao' && $row->valeur == 'TRANSFERE') ? "disabled='disabled'" : "";
							$selectedOption	= ($row->valeur == $valeur) ? "selected='selected'" : "";
							$optionHtml .= "<option $selectedOption $disabledOption value='".$row->id."'>".$options[$row->id]."</option>";
						}
					}
					$extraClasse = '';
					$extraParams = '';
					if($champObj->idType == 18){
						$extraClasse .= ' eg-select2-multiple';
						$extraParams = 'multiple="multiple" id="id-'.$name.'"';
						if(!$modeEditionInline){
							$htmlOP .= '<input type="checkbox" class="editable-input eg-liste-multiple-chk" name="'.$name.'__chk" id="id-'.$name.'__chk" /> <label for="id-'.$name.'__chk">Ajouter la/les valeur(s)</label>';
						}
						$htmlOP .= '<select class="form-control editable-input '.$extraClasse.'" name="'.$name.'[]" '.$extraParams.'>';
					}else{
						$htmlOP .= '<select class="form-control editable-input '.$extraClasse.'" name="'.$name.'" '.$extraParams.'>';
					}
					
					if($allFields) {
						$htmlOP .= '<option value="">Choisissez</option>';
					}
					$htmlOP .= $optionHtml;
					if($champObj->idType == 18 && !$modeEditionInline){
						$htmlOP .= '<option value="0">Valeur vide</option>';
					}else{
						$htmlOP .= '<option value="">Valeur vide</option>';
					}
					$htmlOP .= '</select>';
					
				} elseif ($champObj->sourceListe == "statut_docs") {
					$rows = $this->getTableObjet('statut_docs')->select();
					$optionHtml = '<option value="">Vide</option>';
					foreach ($rows as $row) {
						$cle = $row->id;
						$options[$cle] = $row->nom;

						if ($row->nom == $valeur) {
							$optionHtml .= '<option selected="selected" value="'.$cle.'">'.$options[$cle].'</option>';
						} else {
							$optionHtml .= '<option value="'.$cle.'">'.$options[$cle].'</option>';
						}
					}
					$htmlOP .= '<select class="form-control editable-input" name="'.$name.'">';
					$htmlOP .= $optionHtml;
					$htmlOP .= '</select>';
				} elseif ($champObj->sourceListe == "user") {
					$rows = array();
					$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql' => 'idUser'))->current();
					$codeType = '';
					if ($champObj->options && substr($champObj->options, 0, 8) == 'codeType') {
						$codeType = str_replace('codeType_', '', $champObj->options);
					} elseif ($cb && $cb->critere) {
						$codeTypeArr = json_decode($cb->critere, true);
						if (!empty($codeTypeArr['codeType'])) {
							$codeType = $codeTypeArr['codeType'];
						}
					}

					if ($codeType) {
						$rows = $this->getUserTable()->getUsersListeByCodeType($codeType, $idCampagne, $idResidenceUser);
						$usersDeleted = $this->getUserTable()->getUsersDeletedByCodeType($codeType, $idCampagne, $idResidenceUser);
						foreach ($rows as $cle => $row) {
							$options[$cle] = $row;
							$extraOptions = "";
							if (array_key_exists($cle, $usersDeleted)) {
								if ($valeur && $valeur == $cle) {
									//$extraOptions = 'disabled="disabled"';
								} else {
									continue;
								}
							}
							if ($row == $valeur) {
								$optionHtml .= '<option '.$extraOptions.' selected="selected" value="'.$cle.'">'.$options[$cle].'</option>';
							} else {
								$optionHtml .= '<option '.$extraOptions.' value="'.$cle.'">'.$options[$cle].'</option>';
							}
						}
						$extraClasse = '';
						$extraParams = '';
						if($champObj->idType == 18){
							$extraClasse .= ' eg-select2-multiple';
							$extraParams = 'multiple="multiple"';
							if(!$modeEditionInline){
								$htmlOP .= '</div><div><input type="checkbox" class="editable-input eg-liste-multiple-chk" name="'.$name.'__chk" /> Ajouter la/les valeur(s)';
							}
							$htmlOP .= '<select class="form-control editable-input '.$extraClasse.'" name="'.$name.'[]" '.$extraParams.'>';
						}else{
							$htmlOP .= '<select class="form-control editable-input '.$extraClasse.'" name="'.$name.'" '.$extraParams.'>';
						}
						
						if($allFields) {
							$htmlOP .= '<option value="">Choisissez</option>';
						}
						$htmlOP .= $optionHtml;
						$htmlOP .= '</select>';
					}
				} elseif ($champObj->idType == '2') {
					//Date
					$valeur = $valeur ? date('d-m-Y', strtotime($valeur)) : '';

					$htmlViewPart = new ViewModel();
					$htmlViewPart->setTerminal(true)
							->setTemplate('reservation/liste/dateinput')
							->setVariables(array(
								  'name' => $name,
								  'value' => $valeur,
								  'plage' => $this->getPlageDeDate($champObj->id),
								  'modeEditionInline' => $modeEditionInline,
							));

					$htmlOP .= $this->getServiceLocator()
							->get('viewrenderer')
							->render($htmlViewPart);
				} elseif ($champObj->idType == "8") {
					## type checkbox
					$checked	= $valeur ? "checked" : "";
					$htmlOP .= '<input type="checkbox" class="editable-input" name="'.$name.'" '.$checked.' />';
				} elseif ($champObj->idType == "9") {
					## radio
					$opts = explode(";", $champObj->options);
					//on supprime les element vide
					$options = array_filter($opts);
					foreach ($options as $index => $lib) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=$champ valeur=$valeur index=$index lib=$lib");
						$checked	= $index == $valeur ? "checked" : "";
						$htmlOP .= '<label class="margin-right-10">';
						$htmlOP .= '<input type="radio" name="'.$name.'" value="'.$index.'" class="editable-input" '.$checked.' />';
						$htmlOP .= $lib;
						$htmlOP .= '</label>';
					}
				} elseif ($champObj->idType == "4") {
					## Document
					$idLocataire = null;
					if ($idResa) {
						$res = $this->getResaTable()->getResa($idResa);
						$idLocataire = $res->idLocataire;
					}

					$htmlViewPart = new ViewModel();
					$htmlViewPart->setTerminal(true)
						->setTemplate('reservation/liste/fileinput')
						->setVariables(array(
							  'name' => $name,
							  'validerFichier' => $validerFichier,
							  'modeEditionInline' => $modeEditionInline,
							  'idLocataire' => $idLocataire,
							  'value' => $valeur,
							  'idResa' => $idResa,
							  'idDp' => $idDp,
						));

					$htmlOP .= $this->getServiceLocator()
						->get('viewrenderer')
						->render($htmlViewPart);
				} else {
					$htmlOP .= '<input type="text" class="form-control editable-input" name="'.$name.'" value="'.$valeur.'" />';
				}
			}
		}

		//cas intercontrat
		if ($champ == 'intercontrat') {
			$etats = $this->getEtatIntercontratTable()->select(array('default' => 0));
			$htmlOP .= '<select class="form-control editable-input" name="'.$champ.'" style="width:70%;margin-right:5px;float:left">';
			foreach ($etats as $ic) {
				$htmlOP .= '<option value="'.$ic->id.'">'.$ic->nom.'</option>';
			}
			$htmlOP .= '</select>';
			$htmlOP .= '<input type="number" class="form-control" name="dureeIntercontrat" value="1" min="1" placeholder="Duree" style="width:25%;" />';
		}

		// echo 'champ:'.$champ;die();
		// cas serrures
		// if($champ == 'intercontrat'){
		// $etats = $this->getEtatIntercontratTable()->select(array('default'=>0));
		// $htmlOP .= '<select class="form-control editable-input" name="'.$champ.'" style="width:70%;margin-right:5px;float:left">';
		// foreach($etats as $ic){
		// 	$htmlOP .= '<option value="'.$ic->id.'">'.$ic->nom.'</option>';
		// }
		// $htmlOP .= '</select>';
		// $htmlOP .= '<input type="number" class="form-control" name="dureeIntercontrat" value="1" min="1" placeholder="Duree" style="width:25%;" />';
		// }

		$htmlOP .= '<input type="hidden" name="tableSource" value="'.$source.'" />';
		$htmlOP .= '<input type="hidden" name="tableName-'.$name.'" value="'.$tableSource.'" />';

		$htmlOP .= '</div>';
		return $htmlOP;
	}


	//Validation de lupload de document dans la liste(edition de champs direct)
	public function validerdocumentAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$isResa = (int) $request->getPost('isResa');
			$fileName = $request->getPost('fileName');
			$champCode = $request->getPost('champCode');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa isResa=$isResa fileName=$fileName chamCode=$champCode");

			$idLocataire = null;
			$newName = "";

			if ($isResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				if ($resa) {
					//on copie le fichier uploader vers le repertoire du locataire, et on maj le champs dans la bdd
					//on cree un newName pour avoir l idLocataire dans le nom de fichier

					$extension = pathinfo($fileName, PATHINFO_EXTENSION);
					$nomFichier = pathinfo($fileName, PATHINFO_FILENAME);
					$newName = $nomFichier.$resa->idLocataire.".".$extension;


					$this->copyLocatairesDocs($fileName, array($idResa), $newName);
					//on save
					$champ  = $this->getTable('champs')->select(array('code' => $champCode))->current();
					if ($champ && $champ->table && $champ->equivalentSql) {
						$idLocataire = $resa->idLocataire;

						$table = $champ->table;

						$data = array($champ->equivalentSql => $newName);
						if ($table == "locataires") {
							$where = array('id' => $idLocataire);
							$this->getTable($table)->update($data, $where);
						} elseif ($table == "reservations") {
							$where = array('id' => $idResa);
							if ($champ->equivalentSql == "certificatAssur") {
								$data['statutAssur'] = null;
							}

							$this->getTable($table)->update($data, $where);
						} elseif ($table == "plai_ressources") {
							$where = array('idResa' => $idResa);
							if ($champ->equivalentSql == "preuveHandicap") {
								$data['statutPreuveHandicap'] = null;
							}
							if ($champ->equivalentSql == "preuveHandicapEntree") {
								$data['statutPreuveHandicapEntree'] = null;
							}
							$this->getTableObjet($table)->update($data, $where);
						}
					} elseif (!$champ) {
						$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
						$select = $champsFormulaireTable->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.equivalentSql' => $champCode, 'champs_formulaires.idType' => 4, 'champs_formulaires.nature' => 'libre'));
						$champ = $champsFormulaireTable->selectWith($select)->current();
						if ($champ) {
							$tableVD = $this->getTableObjet('valeurs_dynamiques');
							$r = $tableVD->select(array('idChamp' => $champ->id, 'idReservation' => $idResa))->current();
							if ($r) {
								$tableVD->update(array('valeur' => $newName), array('id' => $r->id));
							} else {
								$tableVD->insert(array('valeur' => $newName, 'idChamp' => $champ->id, 'idReservation' => $idResa, 'idLocataire' => $resa->idLocataire));
							}
						}
					}
				}
			}




			$view = new JsonModel(array(
						'success' => true,
						'fileName' => $newName,
						'idLocataire' => $idLocataire,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	public function fileuploadAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] FILES=".json_encode($_FILES));
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			//print_r($_FILES);

			if (!is_dir(getcwd()."/public/docs/locataires/tmp")) {
				mkdir(getcwd()."/public/docs/locataires/tmp");
			}

			$folder = "./public/docs/locataires/tmp";
			$dossier = "docs/locataires/tmp";
			$passer = 0;//0:pas fourni , 1:pas chargé, 2:extension non valide, 3:uploader
			$namePJ = "";

			$filedName = "";
			$champId = "";
			if (isset($_FILES['attestationBourse'])) {
				$filedName = "attestationBourse";
			} elseif (isset($_FILES['certificatMedical'])) {
				$filedName = "certificatMedical";
			} elseif (isset($_FILES['certificatAssur'])) {
				$filedName = "certificatAssur";
			} elseif (isset($_FILES['certificatAssur'])) {
				$filedName = "certificatAssur";
			} elseif (isset($_FILES['preuveHandicap'])) {
				$filedName = "preuveHandicap";
			} elseif (isset($_FILES['preuveHandicapEntree'])) {
				$filedName = "preuveHandicapEntree";
			} else {
				##le document dynamique
				//$session = new Container('extra');
				//$docsFields = $session->docsFields;

				$docsFields = $this->getTableObjet('champs_formulaires')->select(array('idType' => 4, 'nature' => 'libre', 'active' => '1'));

				foreach ($docsFields as $row) {
					if (isset($_FILES[$row->equivalentSql])) {
						$filedName = $row->equivalentSql;
						$champId = $row->equivalentSql;
						break;
					}
				}
			}

			if (isset($_FILES[$filedName]) && $_FILES[$filedName]['error'] == 0) {
				$passer = 1;

				$extension = pathinfo($_FILES[$filedName]['name'], PATHINFO_EXTENSION);
				$filename = pathinfo($_FILES[$filedName]['name'], PATHINFO_FILENAME);

				$nameDoc = "pj_".$this->removeAccent($filename)."_".date('Y-m-d-his').".".$extension;
				$nameDoc = date('Ymd')."_".$filedName."_".$idLoc.".".$extension;
				$notallowed = array('exe');

				if (in_array(strtolower($extension), $notallowed)) {
					$passer = 2;
				} else {

					//unlink($folder.'/'.$conf->logo);

					if (move_uploaded_file($_FILES[$filedName]['tmp_name'], $folder.'/'.$nameDoc)) {
						//upload réussi

						$passer = 3;
					}
				}
			}


			$msg = "";
			switch ($passer) {
				case 0: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 1: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 2: $msg = "<span class='error red'>Erreur extension(seulement pdf autorisé)</span>";
					break;
				case 3: $msg = "<span class=' green'>Fichier uploader : <a class='doc-link pj-link' href='#' target='_blank'>$nameDoc </a></span>";
					break;
			}


			$view = new JsonModel(array(
						'success' => true,
						'passer' => $passer,
						'msg' => utf8_encode($msg),
						'docname' => $nameDoc,
						'pjname' => $nameDoc,
						'dossier' => $dossier,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadFicheLocataireTabAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$htmlOP = null;
		$locForm = new LocataireForm();
		$resaForm = new ResaForm();
		$conf = $this->getConfigurationTable()->getConfig(1);

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$tab = $request->getPost('tab');
			$isResa = $request->getPost('isResa');
			$id = $request->getPost('id');
			$idDp = $request->getPost('idDp');
			$modeResa = $request->getPost('mode');
			$couleurAccordion = $request->getPost('couleur', '');
			$idLoc = $request->getPost('idLocataire', 0);
			$numeroLogement = $request->getPost('numeroLogement', "");
			$idResaADupliquer = $request->getPost('idResaADupliquer', 0);
			$memeUsager = $request->getPost('memeUsager', 0);//dupliquer la résa pour le meme usager
			$idCampagneDossier = $request->getPost('idCampagne', 0);//idCampagne pour créer un nouveau dossier

			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

			// var_dump($numeroLogement);die();

			// $idCampagneFromParams = $request->getPost('idCampagne');
			// $idCampagneTypeFromParams = $request->getPost('idCampagneType');

			## idRessource pour le cas ajout de resa depuis le planning
			$idRessource = $request->getPost('idRessource');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa idResa=$id mode=$modeResa tab=$tab idRessource=$idRessource dateDebut=$dateDebut dateFin=$dateFin");

			//params à envoyer au fonction loadongletXXX
			$resaParams = array();
			$resaParams['isResa'] = $isResa;
			$resaParams['idResa'] = $id;
			$resaParams['idRessource'] = $idRessource;
			$resaParams['dateDebut'] = $dateDebut;
			$resaParams['dateFin'] = $dateFin;
			$resaParams['modeResa'] = $modeResa;
			$resaParams['idLocataire'] = $idLoc;

			$titreFicheLocataire = "";
			$photoFicheLocataire = "";

			$params = array();
			$idCampagne = $idResa = $idProgramme = $idSousProgramme = 0;

			//si on ajoute la resa depuis le planning, on recupère les date arrivee et depart, et le logmeent
			$isResaManuelle = false;
			$isResaDupliquer = false;

			if ($isResa == -1 && $idDp) {
				// $tab = 'ficheLocataire';
				//$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
				$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
				$idLocataire = $dp->idLocataire;
				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				if ($loc) {
					$titreFicheLocataire = $loc->nom.' '.$loc->prenom;
					if ($_SESSION['USERDROIT']['ficheclient/ficheLocataireAvecPhoto'] == 'W' || $_SESSION['USERDROIT']['ficheclient/ficheLocataireAvecPhoto'] == 'R') {
						if ($loc->photo) {
							$photoFicheLocataire = "/docs/locataires/$idLocataire/".$loc->photo;
						}
					}
				}
				//$campagneTypeDp = $this->getTableObjet('campagnes_type')->select(array('code'=>'dp'))->current();
				//$campagneDp = $this->getTableObjet('campagnes')->select(array('type'=>$campagneTypeDp->id))->current();
				//$idCampagne = $campagneDp->id;
				//$campagneDp = $this->getTableObjet('campagnes')->select(array('id'=>$dp->idCampagne))->current();
				$idCampagne = $dp->idCampagne;
			} elseif ($idResaADupliquer > 0) {
				$resaADupliquer = $this->getResaTable()->getResa($idResaADupliquer);
				if ($resaADupliquer) {
					$isResaDupliquer = true;
					$idCampagne = $resaADupliquer->idCampagne;
					$params['idResaADupliquer'] =  $idResaADupliquer;
					$params['memeUsager'] = $memeUsager;
				}
			} elseif ((!$idRessource || $isResa != -1) && !$idCampagneDossier) {
				$resa = null;
				if ($isResa == 1) {
					$idReservation = $idResa = $id;
					$resa = $this->getResaTable()->getResa($idReservation);
					$idLocataire = $resa->idLocataire;
					$idCampagne =  $resa->idCampagne;
				} else {
					$idLocataire = $id;
				}

				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				if ($loc) {
					$titreFicheLocataire = $loc->nom.' '.$loc->prenom;
					if ($conf->titreFicheUsager == "nom_prenom_numeroChambre" && $resa && $resa->numeroChambre) {
						$titreFicheLocataire .= ' - '.$resa->numeroChambre;
					}
					if ($_SESSION['USERDROIT']['ficheclient/ficheLocataireAvecPhoto'] == 'W' || $_SESSION['USERDROIT']['ficheclient/ficheLocataireAvecPhoto'] == 'R') {
						if ($loc->photo) {
							$photoFicheLocataire = "/docs/locataires/$idLocataire/".$loc->photo;
						}
					}
				}
			} else {
				//ajout

				$id = 0;
				$idLocataire = 0;
				$loc = null;

				$isResaManuelle = true;
				$params['dateArrivee'] =  $dateDebut;
				$params['dateDepart'] =  $dateFin;
				$params['idLogement'] =  $idRessource;

				$campFixe = $this->getTableObjet('campagnes')->select(array('fixe' => 1))->current();
				if (empty($idDp)) {
					$idCampagne = $campFixe ? $campFixe->id : 0;
				}
				if($idCampagneDossier > 0) {
					$idCampagne = $idCampagneDossier;
					$params['nouveauDossier'] = true;
				}

				// if (isset($idCampagneFromParams) && !empty($idCampagneFromParams)
				// 	&& isset($idCampagneTypeFromParams) && !empty($idCampagneTypeFromParams)) {
				// 	$idCampagne = $request->getPost('idCampagne');
				// }
			}

			// ajout tabs type suivis
			$typesSuivis = $this->getListeTypesSuivis();
			$tabsSuivis = array();
			$typeSuiviDp = $this->getTableObjet('type_suivi')->select(array('type_suivi' => 'courriers', 'deleted' => 0))->current();
			$idTypeSuivis = $typeSuiviDp ? $typeSuiviDp->id : null;

			foreach ($typesSuivis as $idType => $type) {
				$tabsSuivis['ficheSuivis'.$idType] = $idType;
			}

			## fiche catalogues tabs
			$typesCatalogue = $this->getCatalogueTable()->getTypesCatalogueListe(array('autre', 'animation'));
			$tabsCatalogue = array();
			foreach ($typesCatalogue as $idType => $type) {
				$tabsCatalogue['ficheCatalogue'.$idType] = $idType;
			}

			## Formulaires tabs
			$ongletsFormulaires = $this->getOngletsFormulairesTable()->fetchAll();
			$tabsForms = array();
			foreach ($ongletsFormulaires as $row) {
				$tabsForms['ficheOngletsFormulaires'.$row->id] = $row->id;
			}

			// Envoyer idResa ou idDp pour charger les logs
			$idParamsLogs = "";
			$isResaLogs = "";
			if ($idDp) {
				$idParamsLogs = $idDp;
				$isResaLogs = -1;
			} else {
				$idParamsLogs = $idResa;
				$isResaLogs = 1;
			}

			//recup de droit de la tab par profil et campagne
			if ($idCampagne) {
				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, $tab);
			} else {
				//si on a pas de campagne on autorise le tout, genre pour le mode Mail SMS etc
				$allowdCamp = true;
			}


			$allAllowedTabs = $this->getAllAlowedTabsByCamp($idCampagne);

			if ($isResa == -1 && $idDp) {
				if ($tab == 'ficheLocataire' && $allowdCamp) {
					$params['couleurAccordion'] = $couleurAccordion;
					$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'idDp' => $idDp, 'params' => $params);
					$htmlOP = $this->loadLocataireTab($locParams);
					if ($htmlOP == "") {
						unset($allAllowedTabs[$tab]);
					}
				} elseif ($tab == 'ficheLogs' && $allowdCamp) {
					$htmlOP = $this->loadLogsTab($idParamsLogs, $isResaLogs);
				} elseif (array_key_exists($tab, $tabsSuivis)) {
					$htmlOP = $this->loadSuivisTab($idResa, $tabsSuivis[$tab], array('idDp' => $idDp));
				} elseif ($tab == 'ficheDocuments' && $allowdCamp) {
					$htmlOP = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp), 'UTF-8', 'UTF-8');
				} elseif ($tab == 'ficheEditionDocuments' && $allowdCamp) {
					$htmlOP = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, true, $idDp), 'UTF-8', 'UTF-8');
				} elseif ($tab == 'ficheDp' && $allowdCamp) {
					$htmlOP = $this->loaddpTab($loc->id, $idDp);
				} elseif (array_key_exists($tab, $tabsCatalogue)) {
					$htmlOP = $this->loadCatalogueTab($idResa, $tabsCatalogue[$tab], array('idDp' => $idDp));
				} elseif ($tab == 'ficheResaCommentaires' && $allowdCamp) {
					$htmlOP = $this->loadCommentairesTab(null, $idDp);
				} elseif (array_key_exists($tab, $tabsForms)) {
					$params['couleurAccordion'] = $couleurAccordion;
					$params['idOnglet'] = $tabsForms[$tab];
					$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'idDp' => $idDp, 'params' => $params);
					$htmlOP = $this->loadLocataireTab($locParams);
				}
				// $inactiviteEnCours = $this->inactiviteEnCours($idDp);
				$inactiviteEnCours = $dp->enCoursInactivite;
				$classTitle = "";
				if ($inactiviteEnCours) {
					$classTitle = "titre-fiche-usager";
				}
				$titreFicheLocataire = '<span class="'.$classTitle.'" title="idDp='.$idDp.' idLocataire='.$loc->id.'">'.$titreFicheLocataire.'</span>';
			} else {
				$resa = $this->getResaTable()->getResa($idResa);
				if ($tab == 'ficheLocataire' && $allowdCamp) {
					$params['couleurAccordion'] = $couleurAccordion;
					$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'params' => $params);
					$htmlOP = $this->loadLocataireTab($locParams);
					if ($htmlOP == "") {
						unset($allAllowedTabs[$tab]);
					}
				} elseif ($tab == 'ficheResa' && $allowdCamp) {
					$htmlOP = $this->loadReservationTab($resaParams);
				} elseif ($tab == 'ficheCompte' && $allowdCamp) {
					$htmlOP = $this->loadComptesTab($idResa);
				} elseif ($tab == 'ficheMail' && $allowdCamp) {
					$htmlOP = $this->loadMailsTab($idLocataire);
				} elseif ($tab == 'ficheDocuments' && $allowdCamp) {
					// var_dump("testlolo",$loc, $idResa);
					$htmlOP = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false), 'UTF-8', 'UTF-8');
				} elseif ($tab == 'ficheEditionDocuments' && $allowdCamp) {
					$htmlOP = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, true), 'UTF-8', 'UTF-8');
				} elseif ($tab == 'ficheIntercontrat' && $allowdCamp) {
					$htmlOP = $this->loadIntercontratTab($resa);
				} elseif ($tab == 'ficheDemandes' && $allowdCamp) {
					$htmlOP = $this->loadDemandesTab($resa);
				} elseif ($tab == 'ficheResaCommentaires' && $allowdCamp) {
					$htmlOP = $this->loadCommentairesTab($resa);
				} elseif ($tab == 'ficheColis' && $allowdCamp) {
					$htmlOP = $this->loadColisTab($resa, array('typeRetour' => 'default'));
				} elseif ($tab == 'fichePrelevements' && $allowdCamp) {
					$htmlOP = $this->loadPrelevementTab($idResa);
				} elseif ($tab == 'fichePaiementEmail' && $allowdCamp) {
					$htmlOP = $this->loadPaiementEmailTab($idResa);
				} elseif ($tab == 'ficheLogs' && $allowdCamp) {
					$htmlOP = $this->loadLogsTab($idParamsLogs, $isResaLogs);
				} elseif (array_key_exists($tab, $tabsSuivis) && $allowdCamp) {
					$htmlOP = $this->loadSuivisTab($idResa, $tabsSuivis[$tab]);
				} elseif ($tab == 'ficheSMS' && $allowdCamp) {
					$htmlOP = $this->loadSMSTab($idLocataire);
				} elseif ($tab == 'ficheAlert' && $allowdCamp) {
					$htmlOP = $this->loadSMSTab($idLocataire, 'btn-alert');
				} elseif ($tab == 'fichePush' && $allowdCamp) {
					// var_dump("fichePush", $idLocataire,$allowdCamp);
					$htmlOP = $this->loadPushTab($idLocataire);
				} elseif ($tab == 'ficheCompteur' && $allowdCamp) {
					$htmlOP = $this->loadCompteurTab($resa);
				} elseif (array_key_exists($tab, $tabsCatalogue) && $allowdCamp) {
					$htmlOP = $this->loadCatalogueTab($idResa, $tabsCatalogue[$tab]);
				} elseif ($tab == 'ficheEDL' && $allowdCamp) {
					$htmlOP = $this->loadEDLTab($idResa, $idLocataire);
				} elseif (array_key_exists($tab, $tabsForms)) {
					$params['couleurAccordion'] = $couleurAccordion;
					$params['idOnglet'] = $tabsForms[$tab];
					$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'params' => $params);
					$htmlOP = $this->loadLocataireTab($locParams);
				} elseif ($tab == 'ficheMembresFamille' && $allowdCamp && $resa->idMenage > 0 /*&& $resa->idStatutFamilial == 1*/) {
					$htmlOP = $this->loadMembresMenage($idResa);
				} elseif ($tab == 'ficheHistoriqueSejours' && $allowdCamp) {
					$htmlOP = $this->loadHistoriqueSejoursTab($loc->id, $idResa);
				} elseif ($tab == 'ficheDp' && $allowdCamp) {
					## Onglet DP Mode Résa -> on passe l'idLocataire mais pas l'idDp
					$htmlOP = $this->loaddpTab($loc->id, 0);
				}

				$titreFicheLocataire = '<span class="" title="idResa='.$idResa.' idLocataire='.$loc->id.'">'.$titreFicheLocataire.'</span>';
				if ($conf->titreFicheUsager == "nom_prenom_numeroChambre" && $resa && $resa->numeroChambre && $resa->idLogement) {
					$adrLogementComplet = $this->getLogementTable()->getAdrLogementComplet($resa->idLogement);
					if(trim($adrLogementComplet) != ''){
						$titreFicheLocataire .= '<div class="btnCopierAdrFicheUsager"><span title="'.$adrLogementComplet.'" class="p-menu-container hb hb-xs spin hb-refresh link"><i class="fa fa-home"></i></span></div>';
					}
				}
				if ($loc->id > 0 && ($_SESSION['USERDROIT']['liste-fiche-resident-login'] == 'W' || $_SESSION['USERDROIT']['liste-fiche-resident-login'] == 'R')) {
					$btnConnectResident =  '/admin/liste/loginEspaceResident/'.$loc->id;
				} else {
					$btnConnectResident = false;
				}

			}

			if (!$resa->idMenage /*|| $resa->idStatutFamilial != 1*/) {
				unset($allAllowedTabs['ficheMembresFamille']);
			}

			## controle onglet suivis, pour ne pas les afficher si on les a dans un sous formulaire
			if (!empty($tabsForms)) {
				foreach ($tabsForms as $onglet => $idOngletFormulaire) {
					//on vérifie si le formulaire a le droit sur cette campagne
					$forms = $this->getFormulaireTableModel()->getAllBOForms($idCampagne, $idProfile, $idOngletFormulaire);
					foreach ($forms as $form) {
						if ($form->idType == 13) {
							$typesSuivisForm = $this->getTypeSuivisFormulaireTable()->getTypeSuivisDeFromulaire($form->id);
							foreach ($typesSuivisForm as $TSF) {
								//on enleve les onglet de base type suivis
								$tabTS = 'ficheSuivis'.$TSF->idTypeSuivis;
								if (array_key_exists($tabTS, $tabsSuivis)) {
									$allowdCampS = $this->getTabsDroitParCampagne($idCampagne, $tabTS);
									if ($allowdCampS) {
										unset($allAllowedTabs[$tabTS]);
									}
								}
							}
						}
					}
				}
			}


			if (!$allowdCamp) {
				$htmlOP = '<h3>Accès interdit</h3>';
			}

			// acces pour l'onglet par défaut
			$droitElements = $this->getTableObjet('droit_elements')
			->select(array('parent_id' => "99", "type" => "menu"))->toArray();

			$nextTab = reset($allAllowedTabs);
			foreach ($droitElements as $key => $de) {
				$droit_configs = $this->getTableObjet('droit_config')
				->select(array('droit_id' => $de['id'], 'role_id' => $idProfile))
				->current();

				if ($droit_configs && $droit_configs->default_list == "1") {
					$nextTab = explode("/", $de['unique_name'])[1];
					break;
				}
			}
			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOP,
						'titreFicheLocataire' => $titreFicheLocataire,
						'btnConnectResident' => $btnConnectResident,
						'photoFicheLocataire' => $photoFicheLocataire,
						'idTypeSuivis' => $idTypeSuivis,
						'allowedTabs' => $allAllowedTabs,
						'nextTab' => $nextTab,
			));

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$id len_htmlOP=".strlen($htmlOP));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadMembresMenage($idResa)
	{
		$resa = $this->getResaTable()->getResa($idResa);
		//on vérifie le chef de famille a des infos rib pour autoriser de les copier vers les ménages
		$msgCheckRIB = $this->isRIBRempli($idResa);//si = 'ok' on a les infos RIB
		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/membresmenage')
		->setVariables(array(
				"menage" => $this->getTableObjet('menages')->select(array('id' => $resa->idMenage))->current(),
				"rows" => $this->getResaTable()->getMembresMenage($resa->idMenage, true),
				"idResa" => $idResa,
				"hasRIB" => ($msgCheckRIB == 'ok') ? true : false,
		));

		$htmlOP = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOP;
	}

	public function loadMembreMenageAction()
	{
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');

			$resa = $this->getResaTable()->getResa($idResa);
			$htmlOP = $titreFiche = "";
			if ($resa) {
				$loc = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
				if ($loc) {
					$titreFiche = $loc->nom.' '.$loc->prenom;
					if ($conf->titreFicheUsager == "nom_prenom_numeroChambre" && $resa && $resa->numeroChambre) {
						$titreFiche .= ' - '.$resa->numeroChambre;
					}
				}
				$locParams = array('idCampagne' => $resa->idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'params' => array('isMembreMenage' => true));
				$htmlOP = $this->loadLocataireTab($locParams);
			} else {
				$htmlOP = "Aucun dossier avec id $idResa trouvé";
			}

			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOP,
						'titreFiche' => $titreFiche,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function copierInfosRIBMenageAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResaMenage = $request->getPost('idResaMenage');
			$idsResasMembre = $request->getPost('ids', array());

			$success = true;
			$msg = '';
			if($idResaMenage && !empty($idsResasMembre)) {
				foreach($idsResasMembre as $idResa) {
					$this->copierRIB($idResaMenage, $idResa);
				}
			} else {
				$success = false;
				if(!$idResaMenage) {
					$msg .= "ID du ménage vide";
				}
				if(empty($idsResasMembre)) {
					$msg .= "Aucun Membre ménage coché";
				}
			}


			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}
	private function copierRIB($idResaMenage, $idResa)
	{
		$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
		$tableVD = $this->getTableObjet('valeurs_dynamiques');
		$select = $tableVD->getSql()->select();
		$select->join('champs_formulaires', 'valeurs_dynamiques.idChamp = champs_formulaires.id', array('idChamp' => 'id', 'idType', 'nomXML'));
		$select->where(array('valeurs_dynamiques.idReservation' => $idResaMenage));
		$select->where("(champs_formulaires.idType IN(15,16) OR champs_formulaires.nomXML = 'rib_nomrib')");
		$rows = $tableVD->selectWith($select);
		$rib = null;
		$bic = null;
		$nomRIB = null;
		foreach ($rows as $row) {
			if ($row->valeur) {
				if ($row->idType == 15) {
					$rib = $row->valeur;
				} elseif ($row->idType == 16) {
					$bic = $row->valeur;
				} elseif ($row->nomXML == 'rib_nomrib') {
					$nomRIB = $row->valeur;
				}
			}
		}
		if($resa && $rib && $bic && $nomRIB) {
			$tableVD = $this->getTableObjet('valeurs_dynamiques');
			$tableCF = $this->getTableObjet('champs_formulaires');
			$select = $tableCF->getSql()->select();
			$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
			$select->where(array('formulaires.idCampagne' => $resa->idCampagne));
			$select->where("(champs_formulaires.idType IN(15,16) OR champs_formulaires.nomXML = 'rib_nomrib')");
			$rows = $tableCF->selectWith($select);
			foreach($rows as $champ) {
				if ($champ->idType == 15) {
					$valeur = $rib;
				} elseif ($champ->idType == 16) {
					$valeur = $bic;
				} elseif ($champ->nomXML == 'rib_nomrib') {
					$valeur = $nomRIB;
				}
				if($valeur) {
					$vdRow = $tableVD->select(array('idReservation' => $idResa, 'idChamp' => $champ->id))->current();
					if(!$vdRow) {
						$vData = array();
						$vData['idLocataire'] = $resa->idLocataire;
						$vData['idReservation'] = $idResa;
						$vData['valeur'] = $valeur;
						$vData['idChamp'] = $champ->id;
						$tableVD->insert($vData);
					} elseif($vdRow && (!trim($vdRow->valeur) || trim($vdRow->valeur) != $valeur)) {
						$tableVD->update(array('valeur' => $valeur), array('id' => $vdRow->id));
					}
				}
			}
		} else {
			if(!$resa) {
				return "Resa $idResa introuvable";
			} else {
				return "Les infos RIB du dossier $idResa ne sont pas complète";
			}
		}
		return 'ok';
	}


	/*=========================================================================
	=            Recuperation du contenu de l'onglet domiciliation            =
	=========================================================================*/
	private function loaddpTab($idLocataire, $idDp)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($idDp) {
			$domiciliation = $this->getTableObjet('domiciliations')->select(array('id' => (int) $idDp))->current();
		} else {
			$campagneDp = $this->getTableObjet('campagnes')->select(array('utiliserDpPourResa' => '1'))->current();
			$domiciliation = $this->getTableObjet('domiciliations')->select(array('idLocataire' => $idLocataire, 'idCampagne' => $campagneDp->id, 'archive' => '0', 'etat' => '1'))->current();
		}

		// Récupération des cartes DP
		$cartesDpHisto = $this->getTableObjet('cartes')->select(array('idLocataire' => (int) $idLocataire))->toArray();
		$currentCarte = $this->getTableObjet('cartes')->select(array('idLocataire' => (int) $idLocataire, 'actif' => '1'))->current();

		if ($domiciliation) {
			// Les dates sont optionnels (avoid 01-01-1970 for empty date)
			if (!empty($domiciliation->dateEntree)) {
				$domiciliation->dateEntree = date('d-m-Y', strtotime($domiciliation->dateEntree));
			}
			if (!empty($domiciliation->dateSortie)) {
				$domiciliation->dateSortie = date('d-m-Y', strtotime($domiciliation->dateSortie));
			}
		}

		// N'afficher dans l'onglet DP que les DP avec état (les lignes domiciliations qui sont réellement des DP)
		$tableDP = $this->getTableObjet('domiciliations');
		$select = $tableDP->getSql()->select();
		$select->where(array('idLocataire' => $idLocataire, 'etat' => ['1', '2', '3']));
		$select->order(array('archive ASC', 'dateEntree DESC'));
		$dpAvecEtat = $tableDP->selectWith($select);

		foreach ($dpAvecEtat as $row) {
			$dpRows[] = (object) $row;
		}

		/*$dpRows = $this->getDomiciliationsTable()->getLocParcours($idLocataire);
		if($domiciliation->idNouvelleDP || $domiciliation->idAncienneDP){
			$dpRowsArr = $dpRows;
			$dpRows = array();
			foreach($dpRowsArr as $index=>$row){
				if($domiciliation->idNouvelleDP){
					if($row->id != $domiciliation->id || $row->ajouterDP == '1'){
						$dpRows[] = $row;
					}
				}elseif($domiciliation->idAncienneDP){
					if($row->id != $domiciliation->idAncienneDP || $row->ajouterDP == '1'){
						$dpRows[] = $row;
					}
				}
			}
		}*/
		/*foreach($dpRows as $row){
			$configParcoursRow = $this->getConfigParcoursTable()->getConfigParCampagne(array($row->idCampagne));

			if(!empty($configParcoursRow[$row->idCampagne]['dateEntree'])){
				$idChampDateEntree = $configParcoursRow[$row->idCampagne]['dateEntree'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp'=>$idChampDateEntree,'idDp'=>$row->id));
				if($val) $row->dateEntree = $val->valeur;
			}
			if(!empty($configParcoursRow[$row->idCampagne]['dateSortie'])){
				$idChampDateSortie = $configParcoursRow[$row->idCampagne]['dateSortie'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp'=>$idChampDateSortie,'idDp'=>$row->id));
				if($val) $row->dateSortie = $val->valeur;
			}
		}*/

		$domiciliationsEtat = $this->getTableObjet('domiciliations_etat')->select()->toArray();
		$domiciliationsMotifs = $this->getTableObjet('domiciliations_motifs')->select()->toArray();

		// récuperation des utilisateurs type Référent DP
		$referentsDP = $this->getReferentsDP($idDp);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/domiciliationtab')
		->setVariables(array(
				"config" => $conf,
				"idLocataire" => $idLocataire,
				"idDp" => $idDp,
				"cartesDpHisto" => array_reverse($cartesDpHisto),
				"currentCarte" => $currentCarte,
				"currentDp" => $domiciliation,
				"domiciliationsEtat" => $domiciliationsEtat,
				"domiciliationsMotifs" => $domiciliationsMotifs,
				"referentsDP" => $referentsDP,
				"dpRows" => $dpRows,
		));

		$htmlOP = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOP;
	}
	/*=====  End of Recuperation du contenu de l'onglet domiciliation  ======*/

	/*==========================================
	=        Carte perdue action DP Tab        =
	==========================================*/
	public function cartePerdueAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isPost()) {
			$idLocataire = $request->getPost('idLocataire');
			// $idDp = $request->getPost('idDp');
			$idCarte = $request->getPost('idCarte');
			$newCarte = $request->getPost('newCarte');

			// 1. Désactiver la carte actuellement active
			if ($newCarte == 'perdue') {
				$updateCarte = [];
				$updateCarte['actif'] = '0';

				$carteUpdated = $this->getTableObjet('cartes')->update($updateCarte, array('id' => (int) $idCarte));
			}

			// 2. Créer une nouvelle carte active
			$tableCartes = $this->getTableObjet('cartes')->insert(array(
				'idLocataire' => (int) $idLocataire,
				'dateCreation' => date('Y-m-d H:i:s', time()),
				'actif' => '1',
				'carteImprimee' => '0',
			));

			// 3. Update de idCarte table domiciliations
			$idNewCarte = $adapter->getDriver()->getLastGeneratedValue();

			$updateDP = [];
			$updateDP['idCarte'] = $idNewCarte;

			$DpUpdated = $this->getTableObjet('domiciliations')
			->update($updateDP, array('idLocataire' => (int) $idLocataire, 'archive' => '0'));

			// Message de retour
			$success = false;
			if ($newCarte == 'perdue') {
				if ($carteUpdated && $tableCartes && $DpUpdated) {
					$success = true;
				}
			} elseif ($newCarte == 'new') {
				if ($tableCartes && $DpUpdated) {
					$success = true;
				}
			}

			$domiciliation = $this->getTableObjet('domiciliations')
			->select(array('idLocataire' => (int) $idLocataire, 'archive' => '0'))->current();

			// on maj la table cartes
			$this->getTableObjet('cartes')
			->update(array('idDp' => $domiciliation->id), array('idLocataire' => $idLocataire, 'actif' => '1'));


			// 4. Logs
			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "BO-Fiche DP Création nouvelle carte - Mise à jour carte domiciliation ".$idNewCarte;
			$log->dataBefore = array();
			$log->dataAfter = $domiciliation;
			$log->tableName = "domiciliations";
			$log->idReservation = null;
			$log->idLocataire = (int) $domiciliation->idLocataire;
			$this->getLogsTable()->saveLogs($log);

			// Reload Tab DP
			$htmlOP = $this->loaddpTab((int) $domiciliation->idLocataire, $domiciliation->id);

			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	/*==========================================
	=              Reload tab dp               =
	==========================================*/
	public function reloadTabDpAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$idDp = $request->getPost('idDp');

			$domiciliation = $this->getTableObjet('domiciliations')->select(array('id' => (int) $idDp))->current();

			// Reload Tab DP
			$htmlOP = $this->loaddpTab((int) $domiciliation->idLocataire, (int) $idDp);

			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	/*==========================================
	=            Update load dp tab            =
	==========================================*/
	public function domiciliationTabAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$conf = $this->getConfigurationTable()->getConfig(1);

		$updated = false;
		$updatedFile = false;

		$data = $request->getPost()->toArray();

		$domiciliation = $this->getTableObjet('domiciliations')->select(array('id' => (int) $data['id']))->current();

		// par défaut le champ contient le nom du doc provenant de la BDD
		$data['docName'] = $domiciliation->docName;

		if (isset($_FILES['cerfaDp']['tmp_name']) && !empty($_FILES['cerfaDp']['name'])) {
			if (($handle = fopen($_FILES['cerfaDp']['tmp_name'], "r")) !== false) {

				// Verifie si le repertoire existe
				$dir = getcwd().'/public/docs/locataires/'.$data['idLocataire'];
				if (!is_dir($dir)) {
					mkdir(getcwd().'/public/docs/locataires/'.$data['idLocataire']);
				}

				// Unique filename => timestamp
				$docName = 'dp-'.time().'-'.$_FILES['cerfaDp']['name'];
				$updatedFile = move_uploaded_file($_FILES['cerfaDp']['tmp_name'], $dir.'/'.$docName);
				if ($updatedFile) {
					$data['docName'] = $docName;
				}
			}
		}

		if (isset($data['id']) && !empty($data['id'])) {
			// Formatage des dates
			$data['dateEntree'] = !empty($data['dateEntree']) ? date('Y-m-d', strtotime($data['dateEntree'])) : null;
			$data['dateSortie'] = !empty($data['dateSortie']) ? date('Y-m-d', strtotime($data['dateSortie'])) : null;
			$data['dateFinValidite'] = !empty($data['dateFinValidite']) ? date('Y-m-d', strtotime($data['dateFinValidite'])) : null;

			if ($data['etat'] == '2') {
				if (!empty($data['idMotif']) && !empty($data['dateSortie'])) {
					$peutUpdate = true;
				} else {
					$peutUpdate = false;
					$msgErr = 'Veuillez rentrer une date de sortie et un motif';
				}
			} else {
				$peutUpdate = true;
			}

			if ($peutUpdate) {
				$updated = $this->getTableObjet('domiciliations')->update($data, array('id' => (int) $data['id']));
			}
		}

		$data['updated'] = $updated || $updatedFile;
		$data['peutUpdate'] = $peutUpdate;
		$data['msgErr'] = $msgErr;

		// Reload dp tab
		$data['htmlOP'] = $this->loaddpTab($data['idLocataire'], $domiciliation->id);
		$view = new JsonModel($data);
		$view->setTerminal(true);
		return $view;
	}

	private function getReferentsDP($idDp)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);

		$referentsDP = [];
		// $sql = "SELECT 	user.user_id AS _id, user.display_name, user_role.role_id, user_role.isTech
		// 		FROM 	user, user_role_linker, user_role
		// 		WHERE	user.user_id = user_role_linker.user_id
		// 		AND		user_role_linker.role_id = user_role.role_id
		// 		AND 	user_role_linker.role_id = 'travailleursocial'";

		if ($dp && $dp->idCampagne) {
			/*$sql = "SELECT 	user.user_id AS _id, user.display_name
					FROM 	user
					LEFT JOIN gestionnaire_campagnes ON gestionnaire_campagnes.idGestionnaire = user.user_id
					WHERE gestionnaire_campagnes.idCampagne='".$dp->idCampagne."' AND user.user_type = (SELECT id FROM type_user WHERE codeType = 'DP')";*/
			$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
			$select = $champsFormulaireTable->getSql()->select();
			$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
			$select->where(array('formulaires.idCampagne' => $dp->idCampagne, 'champs_formulaires.equivalentSql' => 'idUserDp'));
			$champ = $champsFormulaireTable->selectWith($select)->current();
			if ($champ && is_numeric($champ->sourceListe)) {
				$sql = "SELECT valeurs_select.id AS _id, valeurs_select.valeur AS display_name
						FROM valeurs_select
						LEFT JOIN champs_formulaires ON champs_formulaires.sourceListe = valeurs_select.idSelect
						LEFT JOIN formulaires ON formulaires.id = champs_formulaires.idFormulaire
						WHERE formulaires.idCampagne = '".$dp->idCampagne."' 
						AND champs_formulaires.equivalentSql = 'idUserDp' 
						AND valeurs_select.deleted='0'";
			} elseif ($champ && $champ->sourceListe == 'user') {
				$codeType = 'TS';
				if ($champ->options) {
					$optArr = explode('_', $champ->options);
					if (sizeof($optArr) == 2) {
						$codeType = $optArr[1];
					}
				}

				## Rendre référent tous les utilisateurs ayant accès à la campagne DP
				/*$sql = "SELECT 	user.user_id AS _id, user.display_name, user.deleted as _deleted
					FROM 	user
					LEFT JOIN gestionnaire_campagnes ON gestionnaire_campagnes.idGestionnaire = user.user_id
					WHERE 	user.user_type = (SELECT id FROM type_user WHERE codeType = '".$codeType."')
					AND gestionnaire_campagnes.idCampagne = '".$dp->idCampagne."'";*/

				$sql = "SELECT 	user.user_id AS _id, user.display_name, user.deleted as _deleted
					FROM 	user
					LEFT JOIN gestionnaire_campagnes ON gestionnaire_campagnes.idGestionnaire = user.user_id
					WHERE gestionnaire_campagnes.idCampagne = '".$dp->idCampagne."'";
			}
		} else {
			$sql = "SELECT 	user.user_id AS _id, user.display_name, user.deleted as _deleted
					FROM 	user
					WHERE 	user.user_type = (SELECT id FROM type_user WHERE codeType = 'TS')";
		}
		//echo $sql;exit();
		if (isset($sql) && !empty($sql)) {
			$results = $adapter->query($sql)->execute();
			foreach ($results as $result) {
				$referentsDP[] = $result;
			}
		}

		return $referentsDP;
	}


	/*=====  End of Update load dp tab  ======*/

	public function loadformdpAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idDp = $request->getPost('idDp', 0);
			$idLocataire = $request->getPost('idLocataire', 0);

			if ($idDp) {
				$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			} else {
				$dp = $this->getTableObjet('domiciliations')->select(array('idLocataire' => $idLocataire, 'etat' => '1', 'archive' => '0'))->current();
			}

			$domiciliationsEtat = $this->getTableObjet('domiciliations_etat')->select()->toArray();
			$domiciliationsMotifs = $this->getTableObjet('domiciliations_motifs')->select()->toArray();
			$referentsDP = $this->getReferentsDP($idDp);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/formdp')
			->setVariables(array(
				"idDp" => $idDp,
				"idLocataire" => $dp ? $dp->idLocataire : $idLocataire,
				"domiciliation" => null,
				"domiciliationsEtat" => $domiciliationsEtat,
				"domiciliationsMotifs" => $domiciliationsMotifs,
				"referentsDP" => $referentsDP,
			));

			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
				'htmlOP' => $htmlOP,
				'dpDejaActive' => $dp ? $dp->etat : '',
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function ajouterdpAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idDp = $request->getPost('idDp', 0);
			$idLocataire = $request->getPost('idLocataire', 0);

			// $currentDp = $this->getDomiciliationsTable()->getCurrentDp($idLocataire);
			if ($idDp) {
				$data = $request->getPost()->toArray();
				unset($data['idDp']);

				$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);

				$success = false;

				if (isset($_FILES['cerfaDp']['tmp_name']) && !empty($_FILES['cerfaDp']['name']) && $dp->etat == '1') {
					if (($handle = fopen($_FILES['cerfaDp']['tmp_name'], "r")) !== false) {

						// Verifie si le repertoire existe
						$dir = getcwd().'/public/docs/locataires/'.$data['idLocataire'];
						if (!is_dir($dir)) {
							mkdir(getcwd().'/public/docs/locataires/'.$data['idLocataire']);
						}

						// Unique filename => timestamp
						$docName = 'dp-'.time().'-'.$_FILES['cerfaDp']['name'];
						$updatedFile = move_uploaded_file($_FILES['cerfaDp']['tmp_name'], $dir.'/'.$docName);
						if ($updatedFile) {
							$data['docName'] = $docName;
						}
					}
				} elseif ($dp->docName) {
					$data['docName'] = $dp->docName;
				}

				if (!empty($data)) {

					// Si la DP en cours est réellement une DP, créer une DP avec copie des champs dynamiques
					// + update de la carte

					// Si la DP n'est pas une DP, update la ligne domiciliations et remplir les champs DP
					// + création d'une carte

					if ($dp->etat) {
						$data['dateEntree'] = !empty($data['dateEntree']) ? date('Y-m-d', strtotime($data['dateEntree'])) : null;
						$data['dateSortie'] = !empty($data['dateSortie']) ? date('Y-m-d', strtotime($data['dateSortie'])) : null;
						$data['dateFinValidite'] = !empty($data['dateFinValidite']) ? date('Y-m-d', strtotime($data['dateFinValidite'])) : null;
						if ($dp) {
							$data['idCampagne'] = $dp->idCampagne;
						}
						if ($dp) {
							$data['idAncienneDP'] = $dp->id;
						}

						$idNewDp = $this->getDomiciliationsTable()->saveDp($data);

						if ($idNewDp) {
							$success = true;
							// on copie les champs dynamiques
							$tableValDyn = $this->getTableObjet('valeurs_dynamiques');
							$valDynRows = $tableValDyn->select(array('idDp' => $idDp));
							foreach ($valDynRows as $row) {
								$vData = array();
								$vData['idDp'] = $idNewDp;
								$vData['idChamp'] = $row->idChamp;
								$vData['valeur'] = $row->valeur;
								$vData['statutDoc'] = $row->statutDoc;
								$vData['idLocataire'] = $idLocataire;
								$tableValDyn->insert($vData);
							}

							// Carte
							$carteLocataire = $this->getTableObjet('cartes')->select(array('idLocataire' => $idLocataire, 'actif' => '1'))->current();
							if ($carteLocataire) {
								$this->getTableObjet('cartes')->update(array('idDp' => $idNewDp), array('id' => $carteLocataire->id));
								$this->getTableObjet('domiciliations')->update(array('idCarte' => $carteLocataire->id), array('id' => $idNewDp));
								$idCarte = $carteLocataire->id;
							}

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO-Fiche DP Ajout nouvelle domiciliation ".$idNewDp;
							$log->dataBefore = array();
							$log->dataAfter = $data;
							$log->tableName = "domiciliations";
							$log->idReservation = null;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);

							// on archive l'ancien DP et on passe son état à Terminé -> etat = 2
							$this->getDomiciliationsTable()->archiver($idDp);
							$this->getTableObjet('domiciliations')->update(array('etat' => '2', 'ajouterDP' => 1, 'idNouvelleDP' => $idNewDp), array('id' => $idDp));

							// Faire suivre les documents de la dp
							$tableDocumentDp = $this->getTableObjet('document_dp');
							$tableDocumentDp->update(array('idDp' => $idNewDp), array('idDp' => $idDp));

							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO Archivage domiciliation $idDp après ajout ";
							$log->dataBefore = array('archive' => '0');
							$log->dataAfter = array('archive' => '1');
							$log->tableName = "domiciliations";
							$log->idReservation = null;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);
						}
					} else {

						// Check si le locataire a déja une carte
						$carteLocataire = $this->getTableObjet('cartes')->select(array('idLocataire' => $idLocataire, 'actif' => '1'))->current();
						if ($carteLocataire) {
							$this->getTableObjet('cartes')->update(array('idDp' => $dp->id), array('id' => $carteLocataire->id));
							$idCarte = $carteLocataire->id;
						} else {
							// Création de la carte
							$dataCarte = array('idDp' => $dp->id, 'idLocataire' => $idLocataire, 'dateCreation' => date("Y-m-d H:i:s"), 'actif' => '1', 'carteImprimee' => '0');
							$carteInsert = $this->getTableObjet('cartes')->insert($dataCarte);
							$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
							$idCarte = $adapter->getDriver()->getLastGeneratedValue();
						}

						// Update de la ligne domiciliations pour créer la vraie DP
						$dataUpdate['dateEntree'] = !empty($data['dateEntree']) ? date('Y-m-d', strtotime($data['dateEntree'])) : null;
						$dataUpdate['dateSortie'] = !empty($data['dateSortie']) ? date('Y-m-d', strtotime($data['dateSortie'])) : null;
						$dataUpdate['dateFinValidite'] = !empty($data['dateFinValidite']) ? date('Y-m-d', strtotime($data['dateFinValidite'])) : null;
						$dataUpdate['etat'] = $data['etat'];
						$dataUpdate['idMotif'] = $data['idMotif'];
						$dataUpdate['idUser'] = $data['idUser'];
						$dataUpdate['idCarte'] = $idCarte;

						$updateDP = $this->getTableObjet('domiciliations')->update($dataUpdate, array('id' => $dp->id));

						if ($updateDP) {
							$success = true;

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO-Fiche DP Ajout première DP ".$dp->id;
							$log->dataBefore = array();
							$log->dataAfter = $data;
							$log->tableName = "domiciliations";
							$log->idReservation = null;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);
						}
					}

					## Check si l'image contenant le code barre est créée, sinon générer son code barre
					$genererCodeBarre = false;
					if ($idCarte) {

						if (strlen($idLocataire) < 6) {
							$add0 = 6 - strlen($idLocataire);
							$ch = "";
							for ($i = 0; $i < $add0; $i++) {
								$ch .= "0";
							}
							$codeIdLocataire = $ch . $idLocataire;
						}

						if (strlen($idCarte) < 6) {
							$add0 = 6 - strlen($idCarte);
							$ch = "";
							for ($i = 0; $i < $add0; $i++) {
								$ch .= "0";
							}
							$codeIdCarte = $ch . $idCarte;
						}

						$codeBarre = $codeIdLocataire . "-" . $codeIdCarte;
						if (!file_exists($dir.'/carte/'.$codeBarre.".jpeg")) {
							$genererCodeBarre = true;
						}
					}
				}

				//on recharge la tabDp
				if ($dp->etat) {
					$htmlOP = $this->loaddpTab($idLocataire, $idNewDp);
				} else {
					$htmlOP = $this->loaddpTab($idLocataire, $dp->id);
				}

				$view = new JsonModel(array(
					'success' => $success,
					'htmlOP' => $htmlOP,
					'idNewDp' => $dp->etat ? $idNewDp : $dp->id,
					'genererCodeBarre' => $genererCodeBarre,
					'codeBarre' => $codeBarre,
					'idLocataire' => $idLocataire,
				));
				$view->setTerminal(true);
				return $view;
			} else {

				## Form DP
				## ~~~~~~~
				$data = $request->getPost()->toArray();
				unset($data['idDp']);

				## Doc Cerfa
				## ~~~~~~~~~
				if (isset($_FILES['cerfaDp']['tmp_name']) && !empty($_FILES['cerfaDp']['name'])) {
					if (($handle = fopen($_FILES['cerfaDp']['tmp_name'], "r")) !== false) {

						// Verifie si le repertoire existe
						$dir = getcwd().'/public/docs/locataires/'.$idLocataire;
						if (!is_dir($dir)) {
							mkdir(getcwd().'/public/docs/locataires/'.$idLocataire);
						}

						// Unique filename => timestamp
						$docName = 'dp-'.time().'-'.$_FILES['cerfaDp']['name'];
						$updatedFile = move_uploaded_file($_FILES['cerfaDp']['tmp_name'], $dir.'/'.$docName);
						if ($updatedFile) {
							$dataDp['docName'] = $docName;
						}
					}
				}

				## Créer une DP sur la campagne avec `utiliserDpPourResa` = '1'
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$campagneDp = $this->getTableObjet('campagnes')->select(array('utiliserDpPourResa' => '1'))->current();

				if (!$campagneDp) {
					$view = new JsonModel(array(
						'success' => true,
						'msg' => 'Aucune campagne pour accueillir les DP sur des résas'
					));
					$view->setTerminal(true);
					return $view;
				}

				## Check si le locataire a déja une carte
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$carteLocataire = $this->getTableObjet('cartes')->select(array('idLocataire' => $idLocataire, 'actif' => '1'))->current();
				if ($carteLocataire) {
					$idCarte = $carteLocataire->id;
				}

				## INSERT de la ligne domiciliations pour créer la vraie DP
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$dataDp['idCampagne'] = $campagneDp->id;
				$dataDp['idLocataire'] = $idLocataire;
				$dataDp['dateEntree'] = !empty($data['dateEntree']) ? date('Y-m-d', strtotime($data['dateEntree'])) : null;
				$dataDp['dateSortie'] = !empty($data['dateSortie']) ? date('Y-m-d', strtotime($data['dateSortie'])) : null;
				$dataDp['dateFinValidite'] = !empty($data['dateFinValidite']) ? date('Y-m-d', strtotime($data['dateFinValidite'])) : null;
				$dataDp['etat'] = $data['etat'];
				$dataDp['idMotif'] = $data['idMotif'];
				$dataDp['idUser'] = $data['idUser'];
				$dataDp['idCarte'] = $carteLocataire ? $idCarte : null;

				$insertDp = $this->getTableObjet('domiciliations')->insert($dataDp);
				$idNouvelleDp = $adapter->getDriver()->getLastGeneratedValue();

				## Si pas de carte, en créer une et MAJ idCarte de la nouvelle DP
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if (!$carteLocataire) {
					## Création de la carte
					## ~~~~~~~~~~~~~~~~~~~~
					$dataCarte = array('idDp' => $idNouvelleDp, 'idLocataire' => $idLocataire, 'dateCreation' => date("Y-m-d H:i:s"), 'actif' => '1', 'carteImprimee' => '0');
					$carteInsert = $this->getTableObjet('cartes')->insert($dataCarte);
					$idNouvelleCarte = $adapter->getDriver()->getLastGeneratedValue();
					$updateDp = $this->getTableObjet('domiciliations')->update(array('idCarte' => $idNouvelleCarte), array('id' => $idNouvelleDp));
					$idCarte = $idNouvelleCarte; 
				} else {
					## Update de idDp de la carte
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~

					$checkDpCarteActive = $this->getTableObjet('domiciliations')->select(array('id' => $carteLocataire->idDp))->current();
					if ($checkDpCarteActive->etat == '1') {
						## Regarder si la DP de la carte n'est pas encore active, auquel cas on ne fait rien (cela ne doit jamais arriver mais dans le doute ...)

					} else {
						## Sinon on peut mettre à jour la carte sur la nouvelle DP sans souci
						$this->getTableObjet('cartes')->update(array('idDp' => $idNouvelleDp), array('id' => $carteLocataire->id));
					}
				}

				if ($insertDp) {
					$success = true;

					### save logs
					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO-Fiche DP Ajout première DP depuis fiche réservation, idDp = ".$idNouvelleDp;
					$log->dataBefore = array();
					$log->dataAfter = $data;
					$log->tableName = "domiciliations";
					$log->idReservation = null;
					$log->idLocataire = $idLocataire;
					$this->getLogsTable()->saveLogs($log);
				}

				## Check si l'image contenant le code barre est créée, sinon générer son code barre
				$genererCodeBarre = false;
				if ($idCarte) {

					if (strlen($idLocataire) < 6) {
						$add0 = 6 - strlen($idLocataire);
						$ch = "";
						for ($i = 0; $i < $add0; $i++) {
							$ch .= "0";
						}
						$codeIdLocataire = $ch . $idLocataire;
					}

					if (strlen($idCarte) < 6) {
						$add0 = 6 - strlen($idCarte);
						$ch = "";
						for ($i = 0; $i < $add0; $i++) {
							$ch .= "0";
						}
						$codeIdCarte = $ch . $idCarte;
					}

					$codeBarre = $codeIdLocataire . "-" . $codeIdCarte;
					if (!file_exists($dir.'/carte/'.$codeBarre.".jpeg")) {
						$genererCodeBarre = true;
					}
				}

				## Rechargement Onglet DP mais rester en mode résa ! donc idDp = 0
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$htmlOP = $this->loaddpTab($idLocataire, 0);

				$view = new JsonModel(array(
					'success' => $success,
					'htmlOP' => $htmlOP,
					'idNewDp' => 0,
					'genererCodeBarre' => $genererCodeBarre,
					'codeBarre' => $codeBarre,
					'idLocataire' => $idLocataire,
				));
				$view->setTerminal(true);
				return $view;
			}
		}
		exit();
	}


	## EDITION FICHE LOCATAIRE

	public function editionAction()
	{
		$start = microtime(true);
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$htmlOutputIC = null;
		$locForm = new LocataireForm();
		$resaForm = new ResaForm();

		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$isResa = $request->getPost('isResa');
			$idLocataireFromDp = $request->getPost('idLocataire');
			$idDp = $request->getPost('idDp');
			$fromDp = $request->getPost('fromDp');
			$id = $request->getPost('id');
			$modeResa = $request->getPost('mode');
			$idCampagneType = $request->getPost('idCampagneType');

			## idRessource pour le cas ajout de resa depuis le planning
			$idRessource = $request->getPost('idRessource');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			$tab = $request->getPost('onglet');

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa idResa=$id mode=$modeResa tab=$tab idRessource=$idRessource dateDebut=$dateDebut dateFin=$dateFin");

			//params à envoyer au fonction loadongletXXX
			$resaParams = array();
			$resaParams['isResa'] = $isResa;
			$resaParams['idResa'] = $id;
			$resaParams['idRessource'] = $idRessource;
			$resaParams['dateDebut'] = $dateDebut;
			$resaParams['dateFin'] = $dateFin;
			$resaParams['modeResa'] = $modeResa;

			$timestartFirstForeach = microtime(true);

			$titreFicheLocataire = "";
			$accesInterdit = '<h3>Accès interdit</h3>';

			$params = array();
			$idCampagne = $idResa = 0;
			$idProgramme = $idSousProgramme = 0;
			//si on ajoute la resa depuis le planning, on recupère les date arrivee et depart, et le logmeent
			$isResaManuelle = false;

			$campagnes_type = -1;
			if ($idDp) {
				$dossierDp = $this->getTableObjet('domiciliations')->select(array('id' => (int) $idDp))->current();
				$idLocataire = $dossierDp['idLocataire'];
				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				$titreFicheLocataire = $loc->nom.' '.$loc->prenom;

				$dateEntree = explode('-', $dossierDp->dateEntree);
				$params['dateEntree'] = "".$dateEntree[2]."-".$dateEntree[1]."-".$dateEntree[0]."";

				$dateSortie = explode('-', $dossierDp->dateSortie);
				$params['dateSortie'] = "".$dateSortie[2]."-".$dateSortie[1]."-".$dateSortie[0]."";

				$params['etat'] = $dossierDp->etat;
				$idCampagne = $dossierDp->idCampagne;
			} elseif (!$idRessource || $isResa != '-1') {
				$resa = null;
				if ($isResa == 1) {
					$idReservation = $id;
					$resa = $this->getResaTable()->getResa($idReservation);
					$idResa = $idReservation;

					$idLocataire = $resa->idLocataire;
					$idCampagne =  $resa->idCampagne;

					$lcampagne = $this->getTableObjet('campagnes')->select(array('id' => (int) $idCampagne))->current();
					$campagnes_type = (int) $lcampagne->type;
				} else {
					$idLocataire = $id;
				}

				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				if ($loc) {
					$titreFicheLocataire = $loc->nom.' '.$loc->prenom;
				}
				if ($resa && $resa->numeroChambre && $resa->idLogement) {
					$siteDeLog = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
					$titreFicheLocataire .= ' - '.$resa->numeroChambre;
					if ($siteDeLog) {
						$titreFicheLocataire .= ' - '.$siteDeLog->residence;
					}
				}
			} else {
				//ajout
				$id = 0;
				$idLocataire = 0;
				$loc = null;

				$isResaManuelle = true;
				$params['dateArrivee'] =  $dateDebut;
				$params['dateDepart'] =  $dateFin;
				$params['idLogement'] =  $idRessource;
				$campFixe = $this->getTableObjet('campagnes')->select(array('fixe' => 1))->current();
				$idCampagne = $campFixe ? $campFixe->id : 0;
			}

			// Campagne DP
			$campagne = null;
			if (isset($idCampagneType) && !empty($idCampagneType) && $fromDp) {
				$campagne = $this->getTableObjet('campagnes')->select(array('type' => $idCampagneType))->current();
				//$idCampagne = $campagne->id;
				$campagnes_type = $campagne->type;
			}

			// Fiche loc from dp
			// if (!empty($idLocataireFromDp)) {
			// 	$loc = $this->getLocatairesTable()->getLocataire($idLocataireFromDp);
			// 	if ($loc){
			// 		$titreFicheLocataire = $loc->nom.' '.$loc->prenom;
			// 	}
			// }

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=".$loc->id." idResa=$idResa nom=".$loc->nom." prenom=".$loc->prenom." adresse=".$loc->adresse);

			// CHECKPOINT1
			$debug = 'Checkpoint1 : '.(microtime(true) - $start).' - ';

			$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idDp' => $idDp, 'idResa' => $idResa, 'params' => $params);

			// var_dump($locParams);die();

			// var_dump($loc);die();
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheLocataire');
			if ($allowdCamp) {
				$htmlOutputLoc = $this->loadLocataireTab($locParams);
			} else {
				$htmlOutputLoc = $accesInterdit;
			}

			// CHECKPOINT2
			$debug .= 'Checkpoint2 : '.(microtime(true) - $start).' - ';

			############################## VIEW RENDERGIN RESA ########################
			$htmlOutputResa = $htmlOutputIC = $htmlOutputDemandes = $htmlOutputColis = '';
			if (!isset($idCampagneType) && empty($idCampagneType)) {
				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheResa');
				if ($allowdCamp) {
					$htmlOutputResa = $this->loadReservationTab($resaParams);
				} else {
					$htmlOutputResa = $accesInterdit;
				}

				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheIntercontrat');
				if ($allowdCamp) {
					$htmlOutputIC = $this->loadIntercontratTab($resa);
				} else {
					$htmlOutputIC = $accesInterdit;
				}

				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheDemandes');
				if ($allowdCamp) {
					$htmlOutputDemandes = $this->loadDemandesTab($resa);
				} else {
					$htmlOutputDemandes = $accesInterdit;
				}

				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheColis');
				if ($allowdCamp) {
					$htmlOutputColis = $this->loadColisTab($resa, array('typeRetour' => 'default'));
				} else {
					$htmlOutputColis = $accesInterdit;
				}
			}

			################################## COMPTES ###############################

			//$htmlOutputCompte = $this->loadComptesTab($idResa);

			############################## PARTIE MAIL #####################
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheMail');
			if ($allowdCamp) {
				$htmlOutputMail = $this->loadMailsTab($idLocataire);
			} else {
				$htmlOutputMail = $accesInterdit;
			}

			#####################################Documents###############################

			//$htmlOutputDocuments = $this->loaddocumentsTab($loc,$idResa,false);

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheEditionDocuments');
			if ($allowdCamp) {
				$htmlOutputEditionDocuments =  mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, true, $idDp), 'UTF-8', 'UTF-8');
			} else {
				$htmlOutputEditionDocuments = $accesInterdit;
			}

			##################################INTER-CONTRAT###############################

			// $htmlOutputIC = $this->loadIntercontratTab($resa);

			#############################################################################

			// $htmlOutputDemandes = $this->loadDemandesTab($resa);

			// $htmlOutputColis = $this->loadColisTab($resa,array('typeRetour'=>'default'));
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheResaCommentaires');
			if ($allowdCamp) {
				$htmlOutputResaCommentaires = $this->loadCommentairesTab($resa);
			} else {
				$htmlOutputResaCommentaires = $accesInterdit;
			}

			//if($resa)$htmlOPPrelevement = $this->loadPrelevementTab($resa->id);

			//$timeend = microtime(true);
			//$execution_time = $timeend - $timestart;
			//$page_load_time = number_format($execution_time, 3);
			//echo "<br>Traitements  execute en " . $page_load_time . " sec";exit();
			// CHECKPOINT2
			$debug .= 'Checkpoint2 : '.(microtime(true) - $start).' - ';

			$view = new JsonModel(array(
				'success' => true,
				  'htmlOPLoc' => $htmlOutputLoc,
				'htmlOPResa' => $htmlOutputResa,
				//'htmlOPCompte'=>$htmlOutputCompte,
				'htmlOPMail' => $htmlOutputMail,
				//'htmlOPDocuments'=>$htmlOutputDocuments,
				'htmlOutputIC' => $htmlOutputIC,
				// 'htmlOutputDemandes'=>$htmlOutputDemandes,
				'htmlOutputColis' => $htmlOutputColis,
				'htmlOutputResaCommentaires' => $htmlOutputResaCommentaires,
				'htmlOPEditionDocuments' => $htmlOutputEditionDocuments,
				'titreFicheLocataire' => $titreFicheLocataire,
				'campagnes_type' => $campagnes_type,
				//'htmlOPPrelevement' => $htmlOPPrelevement,
				'debug' => $debug,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	##Fiche locataire : reservation tab
	public function loadReservationTab($resaParams = array())
	{
		$resaForm = new ResaForm();
		$conf = $this->getConfigurationTable()->getConfig(1);
		$newFicheClientModal = $conf->newFicheClientModal ? $conf->newFicheClientModal : false;
		$isResa = $resaParams['isResa'];
		$id = $resaParams['idResa'];
		$idRessource = $resaParams['idRessource'];
		$dateDebut = $resaParams['dateDebut'];
		$dateFin = $resaParams['dateFin'];
		$modeResa = $resaParams['modeResa'];
		$idNewLocataire = !empty($resaParams['idLocataire']) ? $resaParams['idLocataire'] : 0;//id du nouveau locataire creer depuis le planning dispo

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$id dateDebut=$dateDebut dateFin=$dateFin idNewLocataire=$idNewLocataire");

		$msgAlert = '';
		$params = array();
		$idCampagne = 0;
		$idProgramme = $idSousProgramme = 0;
		//si on ajoute la resa depuis le planning, on recupère les date arrivee et depart, et le logmeent
		$isResaManuelle = false;
		if ($isResa == '-1' && $idRessource) {
			$isResaManuelle = true;
			$params['dateArrivee'] =  $dateDebut;
			$params['dateDepart'] =  $dateFin;
			$params['idLogement'] =  $idRessource;
			$campFixe = $this->getTableObjet('campagnes')->select(array('fixe' => 1))->current();
			$idCampagne = $campFixe ? $campFixe->id : 0;
			if ($dateDebut) {
				$resaForm->get('dateArriveeTheorique')->setValue(date('d-m-Y', strtotime($dateDebut)));
			}
			if ($dateFin) {
				$resaForm->get('dateDepartTheorique')->setValue(date('d-m-Y', strtotime($dateFin)));
			}
			$resaForm->get('typre')->setAttribute('disabled', false);
		}




		if (!$idRessource || $isResa != '-1') {
			$resa = null;
			if ($isResa == 1) {
				$idReservation = $id;
				//$resa = $this->getResaTable()->getListe($idReservation)->current();
				$resa = $this->getResaTable()->getResa($idReservation);

				$idLocataire = $resa->idLocataire;
				$idCampagne =  $resa->idCampagne;
			} else {
				$idLocataire = $id;
			}
		} else {
			//ajout
			$id = 0;
			$idLocataire = 0;
			$loc = null;


			$progsDeCamp = $this->getProgrammeTable()->getProgrammesParentDeCampagnes(array($idCampagne))->current();
			if ($progsDeCamp) {
				$idProgramme = $idSousProgramme = $progsDeCamp->id;
				//on cherche le sp
				$spCamp = $this->getProgrammeTable()->getSousProgrammes($progsDeCamp->id)->current();
				if ($spCamp) {
					$idSousProgramme = $spCamp->id;
				}
			}
		}

		if ($idLocataire) {
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire, false);
		}

		//Liste des programmes
		if ($resa) {
			$progs = $this->getProgrammeTable()->getProgrammesParentDeCampagnes(array($resa->idCampagne));
		} else {
			$progs = $this->getProgrammeTable()->getProgrammesParent();
		}

		$progList = array();
		foreach ($progs as $p) {
			$progList[$p->id] = $p->nom;
		}
		asort($progList);


		//sous prog
		$sp = array();

		if ($loc->idProgramme > 0) {
			#$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
			//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

			if ($conf->modeRecupProgCampagne == 'idProgramme') {
				$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
			} elseif ($resa && $resa->idCampagne > 0 && $conf->modeRecupProgCampagne == 'idSousProgramme') {
				$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, array($resa->idCampagne));
			} else {
				$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
			}


			if ($result->count() <= 0) {
				$result = $this->getProgrammeTable()->getProgrammeById($loc->idProgramme);

				$sp[$result->id] = $result->nom;
			} else {
				foreach ($result as $r) {
					$sp[$r->id] = $r->nom;
				}
			}
		} else {
			if ($isResaManuelle) {
				if ($progsDeCamp) {
					$result = $this->getProgrammeTable()->getSousProgrammes($progsDeCamp->id);
					//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

					if ($result->count() <= 0) {
						$result = $this->getProgrammeTable()->getProgrammeById($progsDeCamp->id);

						$sp[$result->id] = $result->nom;
					} else {
						foreach ($result as $r) {
							$sp[$r->id] = $r->nom;
						}
					}
				}
			} else {
				$sp = false;
			}
		}


		$resaForm->get('idProgRes')->setAttribute('options', $progList);

		if (!empty($sp)) {
			asort($sp);
			$resaForm->get('idSousProgRes')->setAttribute('options', $sp);
		}


		//chargement des liste select
		//$tableEtatTravaux = new Tables('demandes_etat_travaux',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		//$etats = $tableEtatTravaux->getTable()->select();
		$tableER = new Tables('etat_reservation', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$etats = $tableER->getTable()->select();
		$etatOption = array();
		foreach ($etats as $row) {
			$etatOption[$row->id] = $row->nom;
		}

		asort($etatOption);
		$resaForm->get('etat')->setAttribute('options', $etatOption);

		$types = $this->getTypelogementTable()->fetchAll();
		$typesOption = array();
		foreach ($types as $row) {
			$typesOption[$row->id] = $row->nom;
		}

		//tri
		asort($typesOption);
		$resaForm->get('idTypeLogementAttribue')->setAttribute('options', $typesOption);

		//$resaForm->get('idTypeLogement1')->setAttribute('options',$typesOption);
		//$resaForm->get('idTypeLogement2')->setAttribute('options',$typesOption);
		//$resaForm->get('idTypeLogement3')->setAttribute('options',$typesOption);

		$maxChoix = 3;//par defaut
		if ($resa) {
			$choix  = $this->getTableObjet('programme_campagne')
								->select(array('idProgramme' => $resa->idSousProgramme, 'idCampagne' => $resa->idCampagne))
								->current();
			if ($choix) {
				$maxChoix = $choix->maxChoix;
			}
		}


		for ($i = 1; $i <= $maxChoix; $i++) {
			$resaForm->add(array(
				 'name' => 'idTypeLogement'.$i,
				 'type' => 'Select',
				  'options' => array(
							'label' => 'Type logement choix '.$i,
							'empty_option' => 'Choisissez',
							'value_options' => $typesOption,
					),
					'attributes' => array(
						  'class' => 'form-control',
						'id' => 'id-idTypeLogement'.$i,
				),
			 ));
		}

		if ($idRessource) {
			$logement = $this->getLogementTable()->getLogement($idRessource);
			$resaForm->get('idLogement')->setValue($idRessource);
			if ($logement) {
				$type = $logement->idTypeLogement;
				$resaForm->get('idTypeLogementAttribue')->setValue($type);
				//$resaForm->get('idTypeLogement1')->setValue($type);
				//$resaForm->get('idTypeLogement2')->setValue($type);
				//$resaForm->get('idTypeLogement3')->setValue($type);
				$resaForm->get('numeroChambre')->setValue($logement->numero);
			}
			if ($dateDebut && $dateFin) {
				$resaForm->get('dateArrivee')->setValue($dateDebut);
				$resaForm->get('dateDepart')->setValue($dateFin);
			}

			if ($idNewLocataire) {
				$resaForm->get('idLocataire')->setValue($idNewLocataire);
			}
		}

		$historiqueResa = array();

		if ($resa) {
			$wlResa = $resa;

			//fusion Bredea
			$return = $this->getReservationPms($resa->id);
			if (!empty($return) && !empty($return['resa'])) {
				$resa = $return['resa'];
				if($resa->numeroChambre != $wlResa->numeroChambre && !$wlResa->idNouvelleResa) {
					$msgAlert = "Alert : numéro de chambre PMS : ".$resa->numeroChambre." est différent de celui de WL : ".$wlResa->numeroChambre;
					$resa->numeroChambre = $wlResa->numeroChambre;
				}
			}

			$resaForm->bind($resa);

			#$resaForm->get('typre')->setAttribute('disabled',true);

			$resaForm->get('codeGoal')->setValue($loc->codeGoal);
			$resaForm->get('codeSharepad')->setValue($loc->codeSharepad);
			if ($loc->codeGoal) {
				$resaForm->get('codeGoal')->setAttribute('readonly', true);
			}

			if ($loc->codeSharepad) {
				$resaForm->get('codeSharepad')->setAttribute('readonly', true);
			}

			$resaForm->get('codeLocataire')->setValue($loc->codeLocataire);

			if ($loc->codeLocataire) {
				$resaForm->get('codeLocataire')->setAttribute('readonly', true);
			}
			if ($loc->login) {
				$resaForm->get('login')->setValue($loc->login);
				$resaForm->get('login')->setAttribute('readonly', true);
			} else {
				//$resaForm->get('login')->setAttribute('class',"hide");
			}
			if ($loc->password) {
				$resaForm->get('password')->setValue($loc->password);
				$resaForm->get('password')->setAttribute('readonly', true);
			} else {
				//$resaForm->get('password')->setAttribute('class',"hide");
			}
			if (trim($resa->methodePaiement) != "") {
				$resaForm->get('methodePaiement')->setValue(1);
			}

			$resaForm->get('idProgRes')->setValue($resa->idProgramme);
			$resaForm->get('idSousProgRes')->setValue($resa->idSousProgramme);

			if ($loc->anneeEtude) {
				$resaForm->get('anneeEtude')->setValue($loc->anneeEtude);
			}
			if ($loc->statutEtudiant) {
				$resaForm->get('statutEtudiant')->setValue($loc->statutEtudiant);
			}

			/*$paiement = $this->getResaTable()->getPaiementDeResa($resa->id);
			if($paiement && $paiement->dateConfirmation){
				$resa->dateConfirmation = date('d-m-Y',strtotime($paiement->dateConfirmation));
				$resaForm->get('dateConfirmation')->setValue($resa->dateConfirmation);
			}*/
			if ($resa->dateConfirmation) {
				$resa->dateConfirmation = date('d-m-Y', strtotime($resa->dateConfirmation));
				$resaForm->get('dateConfirmation')->setValue($resa->dateConfirmation);
			}

			## on check les dates vides
			$dateDemandeReservation = date('Y', strtotime($resa->dateDemandeReservation)) > 2000 ? date('d-m-Y', strtotime($resa->dateDemandeReservation)) : "";
			$dateArrivee = date('Y', strtotime($resa->dateArrivee)) > 2000 ? date('d-m-Y', strtotime($resa->dateArrivee)) : "";
			$dateDepart = date('Y', strtotime($resa->dateDepart)) > 2000 ? date('d-m-Y', strtotime($resa->dateDepart)) : "";
			$dateOption = date('Y', strtotime($resa->dateOption)) > 2000 ? date('d-m-Y', strtotime($resa->dateOption)) : "";
			$dateFinAssur = date('Y', strtotime($resa->dateFinAssur)) > 2000 ? date('d-m-Y', strtotime($resa->dateFinAssur)) : "";

			$dateArriveeTheorique = date('Y', strtotime($resa->dateArriveeTheorique)) > 2000 ? date('d-m-Y', strtotime($resa->dateArriveeTheorique)) : "";
			$dateDepartTheorique = date('Y', strtotime($resa->dateDepartTheorique)) > 2000 ? date('d-m-Y', strtotime($resa->dateDepartTheorique)) : "";

			$dateArriveeDemande = date('Y', strtotime($resa->dateArriveeDemande)) > 2000 ? date('d-m-Y', strtotime($resa->dateArriveeDemande)) : "";
			$dateDepartDemande = date('Y', strtotime($resa->dateDepartDemande)) > 2000 ? date('d-m-Y', strtotime($resa->dateDepartDemande)) : "";

			if ($modeResa == "affecter") {
				//$resaForm->get('etat')->setAttribute('disabled',false);
				$dateOption = date('d-m-Y');
			}

			//si changement logement en attente
			if ($resa->idNouvelleResa) {
				//on check si changement de logement seulement
				$newResa = $this->getResaTable()->getResa($resa->idNouvelleResa);
				if ($newResa && !$newResa->numDossier || $newResa->codeSite == $resa->codeSite) {
					if ($wlResa->dateDepartTheorique) {
						$dateDepartTheorique = date('d-m-Y', strtotime($wlResa->dateDepartTheorique));
					}
					if ($wlResa->dateDepart) {
						$dateDepart = date('d-m-Y', strtotime($wlResa->dateDepart));
					}
					if ($newResa->etat == 15) {
						//on rend disable la date de depart
						$resaForm->get('dateDepart')->setAttribute('disabled', true);
					}
				}
			}
			//si changement de logement sur le meme site
			if ($resa->idAncienneResa) {
				//on mis la date arrivee = celle de WL
				$oResa = $this->getResaTable()->getResa($resa->idAncienneResa);
				if ($oResa && $oResa->codeSite == $resa->codeSite) {
					if ($oResa->dateArrivee) {
						$dateArrivee = date('d-m-Y', strtotime($wlResa->dateArrivee));
					}
					if ($oResa->dateArriveeTheorique) {
						$dateArriveeTheorique = date('d-m-Y', strtotime($wlResa->dateArriveeTheorique));
					}
				}
			}

			$resaForm->get('dateDemandeReservation')->setValue($dateDemandeReservation);
			$resaForm->get('dateArrivee')->setValue($dateArrivee);
			$resaForm->get('dateDepart')->setValue($dateDepart);
			$resaForm->get('dateOption')->setValue($dateOption);
			$resaForm->get('dateFinAssur')->setValue($dateFinAssur);
			$resaForm->get('dateArriveeTheorique')->setValue($dateArriveeTheorique);
			$resaForm->get('dateDepartTheorique')->setValue($dateDepartTheorique);

			$resaForm->get('dateArriveeDemande')->setValue($dateArriveeDemande);
			$resaForm->get('dateDepartDemande')->setValue($dateDepartDemande);
			if($conf->modifierDateArriveeDemande == 1) {
				$resaForm->get('dateArriveeDemande')->setAttribute('readonly', false);
			}

			if($conf->modifierDateDepartDemande == 1) {
				$resaForm->get('dateDepartDemande')->setAttribute('readonly', false);
			}

			$resaForm->get('attestationBourseCheck')->setValue($resa->attestationBourseCheck ? 1 : 0);
			$resaForm->get('certificatMedicalCheck')->setValue($resa->certificatMedicalCheck ? 1 : 0);

			//quand c affecté on change plus les dates arrivee et depart theorique
			if ($resa->etat == 7) {
				//$resaForm->get('dateArriveeTheorique')->setAttribute('disabled',true);
				//$resaForm->get('dateDepartTheorique')->setAttribute('disabled',true);
			}

			## choix de logement
			for ($i = 1; $i <= $maxChoix; $i++) {
				$choix = $this->getChoixTable()
									->fetchBy(array('idReservation' => $resa->id, 'numeroChoix' => $i))
									->current();
				$valeur = $choix ? $choix->idTypeLogement : "";
				$resaForm->get('idTypeLogement'.$i)->setValue($valeur);
				$resaForm->get('idTypeLogement'.$i)->setAttribute('disabled', true);
			}

			## on regarde si on a un modèle de facture pour le dossier sinon on met le cham en readOnly
			if($wlResa && $wlResa->numDossier) {
				$retPDF = $this->lirePasDeFacture($wlResa->id);
				if(!is_array($retPDF) || (is_array($retPDF) && empty($retPDF))) {
					$resaForm->get('pasDeFacture')->setAttribute('disabled', true);
					$resaForm->get('pasDeFacture')->setAttribute('title', "Pas de modéle de facture pour ce dossier");
				}
			}


			## changement de logement
			$historiqueResa = $this->getHistoriqueResa($resa);
			//print_r($historiqueResa);
		} else {
			// ajout
			$resaForm->get('idProgRes')->setValue($idProgramme);
			$resaForm->get('idSousProgRes')->setValue($idSousProgramme);
			$resaForm->get('etat')->setValue(3);
			$resaForm->get('etat')->setAttribute('disabled', true);
		}

		if ($_SESSION['USERDROIT']['zfcadmin/liste'] != 'W' || $_SESSION['USERDROIT']['ficheclient/ficheResa'] != 'W') {
			foreach ($resaForm as $field) {
				$field->setAttribute('disabled', true);
			}
		}

		$campagneType = $this->getCampagneTable()->getCampagneType($idCampagne);

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idCampagne=$idCampagne idResa=".$resa->id);
		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/resa')
		->setVariables(array(
				'form' => $resaForm,
				'resa' => $resa,
				'historiqueResa' => $historiqueResa,
				'isGoal' => $loc->codeGoal ? 1 : 0,
				'lang' => 'fr_FR',
				'maxChoix' => $maxChoix,
				'idCampagne' => $idCampagne,
				'conf' => $conf,
				'campagneType' => $campagneType,
				'campagneMode' => $this->getCampagneTable()->getCampagneMode($resa->idCampagne),
				'msgAlert' => $msgAlert,
				'newFicheClientModal' => $newFicheClientModal,
		));

		$htmlOutputResa = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputResa;
	}

	## Fiche locataire : tab infos
	public function loadLocataireTab($locParams = array())
	{
		$idCampagne = !empty($locParams['idCampagne']) ? $locParams['idCampagne'] : '';
		$idLocataire = !empty($locParams['idLocataire']) ? $locParams['idLocataire'] : '';
		$idDp = !empty($locParams['idDp']) ? $locParams['idDp'] : '';
		$idResa = !empty($locParams['idResa']) ? $locParams['idResa'] : '';
		$params = !empty($locParams['params']) ? $locParams['params'] : null;
		$isResaManuelle = false;
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa locParams=".json_encode($locParams));

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		//$extra = $this->getFormDynamique($idCampagne,$idLocataire, $idResa, $idDp,$params,$idProfile);
		// var_dump($idCampagne);
		// die();

		$extraform = $this->getFormDynamique($idCampagne, $idLocataire, $idResa, $idDp, $params, $idProfile);
		if ($extraform == "") {
			return "";
		}

		$htmlViewPart	= new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/locataire')
		->setVariables(array(
			// 'form' => $locForm,
			//'isGoal' => $loc->codeGoal?1:0,
			'lang' => 'fr_FR',
			'extra' => $extraform,
			//'libelles'=>$libelles,
			'isResaManuelle' => $isResaManuelle,
			'idLocataire' => $idLocataire,
		));
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa");

		$htmlOutputLoc = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

		return $htmlOutputLoc;
	}

	##Fiche locataire : tab mails
	public function loadMailsTab($idLocataire)
	{
		$resultMail = $this->getHistoriquemailTable()->getMails($idLocataire);
		$mails = array();
		foreach ($resultMail as $row) {
			$mails[] = $row;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/mail')
		->setVariables(array(
				'mails' => $mails,
		));

		$htmlOutputMail = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputMail;
	}

	##Fiche locataire : tab SMS
	public function loadSMSTab($idLocataire, $btnType = 'btn-sms')
	{
		$result = $btnType == 'btn-alert' ? $this->getHistoriqueAlertTable()->getAlert($idLocataire) : $this->getHistoriqueSMSTable()->getSMS($idLocataire);
		$rows = array();
		foreach ($result as $row) {
			$rows[] = $row;
		}

		if ($btnType == 'btn-sms') {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/smstab')
			->setVariables(array(
					'rows' => $rows,
			));
		} elseif ($btnType == 'btn-alert') {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/alerttab')
			->setVariables(array(
					'rows' => $rows,
			));
		}


		$htmlOutputMail = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputMail;
	}
	##Fiche locataire : tab Push
	public function loadPushTab($idLocataire)
	{
		$response = $this->forward()->dispatch('Reservation\Controller\Push', ['action' => 'loadPushTab', 'idLocataire' => $idLocataire]);
		return $response->getContent();
		// return $htmlOutputPush;
	}

	## fiche locataire : tab comptes
	public function loadComptesTab($idResa)
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$conf = $this->getConfigurationTable()->getConfig(1);
			$modeLectureCompte = $request->getPost('modeLectureCompte');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa modeLectureCompte=$modeLectureCompte");
			if ($modeLectureCompte == '') {
				$modeLectureCompte	= 1;
			}

			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

			$comptesOld = array();
			//on verifie si  changement de site, et si l ancien dossier est archivé on l'affiche
			$reser = $this->getResaTable()->getResaWithPms($idResa);
			if ($reser && ($oldIdResa = $reser->idAncienneResa)) {
				$oldResa	= $this->getResaTable()->getResaWithPms($oldIdResa);
				if ($oldResa) {
					$idApiPms	= $oldResa->idApiPms;
					$oldIdPMS	= $oldResa->idPMS;
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa oldIdResa=$oldIdResa oldIdPMS=$oldIdPMS/$idApiPms");
				if ($conf->bredea == 1 && $oldResa && $oldIdPMS && $idApiPms) {
					## Connexion au PMS
					## ~~~~~~~~~~~~~~~~
					try {
						$pmsGen	= new PmsGen($adapter, $idApiPms);
						if ($pmsGen) {
							$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
							if (is_object($pms)) {
								$this->pms	= $pms;
							}
						}
						if ($this->pms) {
							if ($this->pms->getClassName() === "Bredea") {
								//on verife si le dossir est archivé on l ajoute
								$dossierBredea = $this->lireDossierBredea($oldResa->id);
								if (!empty($dossierBredea) && $dossierBredea['dossi_trait'] != 'A') {
									$return = $this->loadComptes($oldResa->id, $modeLectureCompte);
									$comptesOld = $return['comptes'];
								}
							}
						} else {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa newPms_$idApiPms injoignable");
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa newPms_$idApiPms exception=".$ex->getMessage());
					}
				}
			}


			if ($conf->bredea == 1 && /*($idPMS = $reser->idPMS) &&*/ ($idApiPms = $reser->idApiPms) /*&& (!is_object($this->pms) || $idApiPms != $this->pms->getIdApiPms())*/) {
				if ($idApiPms) {
					## Connexion au PMS
					## ~~~~~~~~~~~~~~~~
					try {
						$this->pms	= null;
						$pmsGen	= new PmsGen($adapter, $idApiPms);
						if ($pmsGen) {
							$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
							if (is_object($pms)) {
								$this->pms	= $pms;
							}
						}
						if (!$this->pms) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa newPms_$idApiPms injoignable");
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa newPms_$idApiPms exception=".$ex->getMessage());
					}
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms idApiPms_fromPMS=".($this->pms ? $this->pms->getIdApiPms() : "non transmis"));

			$pmsClass	= is_object($this->pms) ? $this->pms->getClassName() : '';
			$return		= $this->loadComptes($idResa, $modeLectureCompte);

			$comptes = $return['comptes'];
			$comptesCaution = $return['comptesCaution'];
			$fraisInitiaux = $return['fraisInitiaux'];
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms nb_comptes=".count($comptes)." nb_cautions=".count($comptesCaution)." nb_fraisInitiaux=".count($fraisInitiaux)." nb_comptesOld=".count($comptesOld));
			if (!empty($comptesOld)) {
				$comptes = array_merge($comptes, $comptesOld);
			}

			//print_r($comptes);
			//$comptes = $this->getComptesTable()->fetchByLoc($idLocataire);

			$prestations = array();
			$presResult = $this->getTableObjet('type_prestation')->select();
			foreach ($presResult as $p) {
				$prestations[$p->id] = $p->type;
			}
		}

		$listeTransactions = array();
		if ($conf->prelevementLoyer == 1) {
			$histoRows = $this->getTableObjet('pile_loyer_historique')
											->select(array('idLocataire' => $reser->idLocataire, 'statutPaiement' => 'ok'));
			foreach ($histoRows as $hr) {
				//Transaction-4055601208
				if ($hr->msg) {
					$numTransaction = str_replace('Transaction-', '', $hr->msg);
					$listeTransactions[] = $numTransaction;
				}
			}
		}

		## on cherche les modeles de docs existant, pour afficher que ceux qu'on
		$tools = new Tools();
		$modelesDocsExists = array();
		$modelesDocs = $this->getTableObjet('type_modeles_docs')->select(array('active' => '1', 'typeModele' => 'reservation'));
		foreach ($modelesDocs as $m) {
			if (is_dir(getcwd()."/public/docs/modeles/".$m->code)) {
				$modFiles = $tools->lireDocumentsDeRepertoire(getcwd()."/public/docs/modeles/".$m->code);
				if (!empty($modFiles)) {
					$modelesDocsExists[$m->id] = $m->code;
				}
			}
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/compte')
		->setVariables(array(
				//'isGoal' => $loc->codeGoal?1:0,
				'idResa' => $idResa,
				'lang' => 'fr_FR',
				'mode' => $modeLectureCompte,
				'comptes' => $comptes,
				'comptesCaution' => $comptesCaution,
				'fraisInitiaux' => $fraisInitiaux,
				'config' => $conf,
				'prestations' => $prestations,
				'docTable' => $this->getDocumentTable(),
				'listeTransactions' => $listeTransactions,
				'modelesDocsExists' => $modelesDocsExists,
				'pmsClass' => $pmsClass,
		));

		$htmlOutputCompte = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputCompte;
	}



	public function editionallAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$isResa = $request->getPost('isResa');
			$id = $request->getPost('id');
			$modeResa = $request->getPost('mode');
			$call = $request->getPost('call', '');

			## idRessource pour le cas ajout de resa depuis le planning
			$idRessource = $request->getPost('idRessource');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');

			//params à envoyer au fonction loadongletXXX
			$resaParams = array();
			$resaParams['isResa'] = $isResa;
			$resaParams['idResa'] = $id;
			$resaParams['idRessource'] = $idRessource;
			$resaParams['dateDebut'] = $dateDebut;
			$resaParams['dateFin'] = $dateFin;
			$resaParams['modeResa'] = $modeResa;

			$timestartFirstForeach = microtime(true);

			$titreFicheLocataire = "";
			$accesInterdit = '<h3>Accès interdit</h3>';

			$params = array();
			$idCampagne = 0;
			$idProgramme = $idSousProgramme = 0;
			//si on ajoute la resa depuis le planning, on recupère les date arrivee et depart, et le logmeent
			$isResaManuelle = false;

			if (!$idRessource || $isResa != '-1') {
				$resa = null;
				if ($isResa == 1) {
					$idReservation = $id;
					$resa = $this->getResaTable()->getResa($idReservation);
					$idResa = $idReservation;

					$idLocataire = $resa->idLocataire;
					$idCampagne =  $resa->idCampagne;
				} else {
					$idLocataire = $id;
				}

				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				if ($loc) {
					$titreFicheLocataire = $loc->nom.' '.$loc->prenom;
					if ($resa && $resa->numeroChambre && $resa->idLogement) {
						$siteDeLog = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						$titreFicheLocataire .= ' - '.$resa->numeroChambre;
						if ($siteDeLog) {
							$titreFicheLocataire .= ' - '.$siteDeLog->residence;
						}
					}
				}
			} else {
				//ajout

				$id = 0;
				$idLocataire = 0;
				$loc = null;

				$isResaManuelle = true;
				$params['dateArrivee'] =  $dateDebut;
				$params['dateDepart'] =  $dateFin;
				$params['idLogement'] =  $idRessource;
				$campFixe = $this->getTableObjet('campagnes')->select(array('fixe' => 1))->current();
				$idCampagne = $campFixe ? $campFixe->id : 0;
				/*if($dateDebut){
					$resaForm->get('dateArriveeTheorique')->setValue(date('d-m-Y',strtotime($dateDebut)));
				}
				if($dateFin){
					$resaForm->get('dateDepartTheorique')->setValue(date('d-m-Y',strtotime($dateFin)));
				}*/


				/*$progsDeCamp = $this->getProgrammeTable()->getProgrammesParentDeCampagnes(array($idCampagne))->current();
				if($progsDeCamp){
					$idProgramme = $idSousProgramme = $progsDeCamp->id;
					//on cherche le sp
					$spCamp = $this->getProgrammeTable()->getSousProgrammes($progsDeCamp->id)->current();
					if($spCamp){
						$idSousProgramme = $spCamp->id;
					}
				}*/
			}



			############################## PARTIE FICHE LOCATAIRE #####################

			/*
			$allPays =  $this->getPaysTable()->fetchAll();
			$paysOption = array();
			$natOption = array();
			foreach ($allPays as $pays){
				$paysOption[$pays->id] = $pays->pays;
				$natOption[$pays->id] = $pays->nationalite;
			}

			$locForm->get('idPays')->setAttribute('options',$paysOption);
			$locForm->get('idNationalite')->setAttribute('options',$natOption);
			//Liste des programmes
			$progs = $this->getProgrammeTable()->getProgrammesParent();
			$progList = array();
			foreach ($progs as $p){
				$progList[$p->id] = $p->nom;
			}
			asort($progList);

			$locForm->get('idProgramme')->setAttribute('options',$progList);

			//sous prog
			$sp = array();

			if($loc->idProgramme > 0){
				$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
				//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

				if($result->count() <= 0){

					$result = $this->getProgrammeTable()->getProgrammeById($loc->idProgramme);

					$sp[$result->id] = $result->nom;

				}else{
					foreach ($result as $r){
						$sp[$r->id] = $r->nom;
					}
				}

			}else{
				if($isResaManuelle){

					if($progsDeCamp){
						$result = $this->getProgrammeTable()->getSousProgrammes($progsDeCamp->id);
						//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

						if($result->count() <= 0){

							$result = $this->getProgrammeTable()->getProgrammeById($progsDeCamp->id);

							$sp[$result->id] = $result->nom;

						}else{
							foreach ($result as $r){
								$sp[$r->id] = $r->nom;
							}
						}
					}
				}else{
					$sp = false;
				}
			}

			if(!empty($sp)){
				asort($sp);
				$locForm->get('idSousProgramme')->setAttribute('options',$sp);
			}


			if($loc){
				$locForm->bind($loc);
				$dateNaissance = date('Y',strtotime($loc->dateNaissance)) > 1970 ? date('d-m-Y',strtotime($loc->dateNaissance)):"";
				$locForm->get('dateNaissance')->setValue($dateNaissance);
			}


			## libelle des champs de base
			$libelles = $this->getChampsDeBaseByCampagneLibelle($idCampagne);

			*/


			############################## PARTIE FICHE RESA #####################
			//Liste des programmes

			/*$resaForm->get('idProgRes')->setAttribute('options',$progList);

			if(!empty($sp)){
				asort($sp);
				$resaForm->get('idSousProgRes')->setAttribute('options',$sp);
			}


			//chargement des liste select
			$tableER = new Tables('etat_reservation',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$etats = $tableER->getTable()->select();
			$etatOption = array();
			foreach($etats as $row){
				$etatOption[$row->id] = $row->nom;
			}

			asort($etatOption);
			$resaForm->get('etat')->setAttribute('options',$etatOption);

			$types = $this->getTypelogementTable()->fetchAll();
			$typesOption = array();
			foreach($types as $row){
				$typesOption[$row->id] = $row->nom;
			}

			//tri
			asort($typesOption);
			$resaForm->get('idTypeLogementAttribue')->setAttribute('options',$typesOption);

			//$resaForm->get('idTypeLogement1')->setAttribute('options',$typesOption);
			//$resaForm->get('idTypeLogement2')->setAttribute('options',$typesOption);
			//$resaForm->get('idTypeLogement3')->setAttribute('options',$typesOption);

			$maxChoix = 3;//par defaut
			if($resa){
				$choix  = $this->getTableObjet('programme_campagne')
									->select(array('idProgramme'=>$resa->idSousProgramme,'idCampagne'=>$resa->idCampagne))
									->current();
				if($choix){
					$maxChoix = $choix->maxChoix;
				}
			}


			for ($i=1; $i <= $maxChoix ; $i++) {

				$resaForm->add(array(
					 'name' => 'idTypeLogement'.$i,
					 'type' => 'Select',
					  'options' => array(
								'label' => 'Type logement choix '.$i,
								'empty_option' => 'Choisissez',
								'value_options' => $typesOption,
						),
						'attributes' => array(
							  'class' => 'form-control',
							'id' => 'id-idTypeLogement'.$i,
					),
				 ));
			}

			if($idRessource){
				$logement = $this->getLogementTable()->getLogement($idRessource);
				$resaForm->get('idLogement')->setValue($idRessource);
				if($logement){
					$type = $logement->idTypeLogement;
					$resaForm->get('idTypeLogementAttribue')->setValue($type);
					//$resaForm->get('idTypeLogement1')->setValue($type);
					//$resaForm->get('idTypeLogement2')->setValue($type);
					//$resaForm->get('idTypeLogement3')->setValue($type);
					$resaForm->get('numeroChambre')->setValue($logement->numero);
				}
				if($dateDebut && $dateFin){
					$resaForm->get('dateArrivee')->setValue($dateDebut);
					$resaForm->get('dateDepart')->setValue($dateFin);
				}
			}

			$historiqueResa = array();

			if($resa){

				//fusion Bredea
				$return = $this->getReservationPms($resa->id);
				if(!empty($return) && !empty($return['resa'])){
					$resa = $return['resa'];
				}

				$resaForm->bind($resa);

				$resaForm->get('codeGoal')->setValue($loc->codeGoal);
				$resaForm->get('codeSharepad')->setValue($loc->codeSharepad);

				$resaForm->get('idProgRes')->setValue($resa->idProgramme);
				$resaForm->get('idSousProgRes')->setValue($resa->idSousProgramme);

				$paiement = $this->getResaTable()->getPaiementDeResa($resa->id);
				if($paiement && $paiement->dateConfirmation){
					$resa->dateConfirmation = date('d-m-Y',strtotime($paiement->dateConfirmation));
					$resaForm->get('dateConfirmation')->setValue($resa->dateConfirmation);
				}

				## on check les dates vides
				$dateDemandeReservation = date('Y',strtotime($resa->dateDemandeReservation)) > 2000 ? date('d-m-Y',strtotime($resa->dateDemandeReservation)):"";
				$dateArrivee = date('Y',strtotime($resa->dateArrivee)) > 2000 ? date('d-m-Y',strtotime($resa->dateArrivee)):"";
				$dateDepart = date('Y',strtotime($resa->dateDepart)) > 2000 ? date('d-m-Y',strtotime($resa->dateDepart)):"";
				$dateOption = date('Y',strtotime($resa->dateOption)) > 2000 ? date('d-m-Y',strtotime($resa->dateOption)):"";
				$dateFinAssur = date('Y',strtotime($resa->dateFinAssur)) > 2000 ? date('d-m-Y',strtotime($resa->dateFinAssur)):"";

				$dateArriveeTheorique = date('Y',strtotime($resa->dateArriveeTheorique)) > 2000 ? date('d-m-Y',strtotime($resa->dateArriveeTheorique)):"";
				$dateDepartTheorique = date('Y',strtotime($resa->dateDepartTheorique)) > 2000 ? date('d-m-Y',strtotime($resa->dateDepartTheorique)):"";

				if($modeResa == "affecter"){
					$resaForm->get('etat')->setAttribute('disabled',false);
					$dateOption = date('d-m-Y');
				}

				$resaForm->get('dateDemandeReservation')->setValue($dateDemandeReservation);
				$resaForm->get('dateArrivee')->setValue($dateArrivee);
				$resaForm->get('dateDepart')->setValue($dateDepart);
				$resaForm->get('dateOption')->setValue($dateOption);
				$resaForm->get('dateFinAssur')->setValue($dateFinAssur);
				$resaForm->get('dateArriveeTheorique')->setValue($dateArriveeTheorique);
				$resaForm->get('dateDepartTheorique')->setValue($dateDepartTheorique);

				$resaForm->get('attestationBourseCheck')->setValue($resa->attestationBourseCheck ? 1 : 0);
				$resaForm->get('certificatMedicalCheck')->setValue($resa->certificatMedicalCheck ? 1 : 0);

				## choix de logement
				for ($i=1; $i <= $maxChoix ; $i++) {

					$choix = $this->getChoixTable()
										->fetchBy(array('idReservation'=>$resa->id,'numeroChoix'=>$i))
										->current();
					$valeur = $choix ? $choix->idTypeLogement:"";
					$resaForm->get('idTypeLogement'.$i)->setValue($valeur);
					$resaForm->get('idTypeLogement'.$i)->setAttribute('disabled',true);
				}



				## changement de logement
				$historiqueResa = $this->getHistoriqueResa($resa);
				//print_r($historiqueResa);

			}else{
				// ajout
				$resaForm->get('idProgRes')->setValue($idProgramme);
				$resaForm->get('idSousProgRes')->setValue($idSousProgramme);
				$resaForm->get('etat')->setValue(3);
				$resaForm->get('etat')->setAttribute('disabled',true);
			}
			*/

			############################## PARTIE COMPTE #####################
			## BREDEA
			/*if($conf && $conf->bredea == 1){

				try{
					$bredea = new BredeaSql();

					if($resa && $resa->numDossier){
						$comptes = array();
						//$residenceDuType = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);

						$codeSite = $resa->codeSite;

						$rData = array('codeSite'=>$codeSite,'numResa'=>$resa->numResa,'numDossier'=>$resa->numDossier,'typre'=>'R');
						if($conf->modeFactureOuExtrait==1){
							$bredeaComptes = $bredea->lireExtraitCompte($rData);

						}else{
							$bredeaComptes = $bredea->lireCompteModeFacture($rData);

						}

						$factures = $bredeaComptes['facture'];
						$cautions = $bredeaComptes['caution'];
						$prets = $bredeaComptes['pret'];



						foreach($factures as $f){
							$f->idReservation = $resa->id;
							$comptes[] = $f;
						}

						foreach($cautions as $c){
							$c->idReservation = $resa->id;
							$comptes[] = $c;
						}

						foreach($prets as $p){
							$p->idReservation = $resa->id;
							$comptes[] = $p;
						}
					}//end if numDossier

					$bredea->closeConnect();
				}catch(\Exception $ex) {
					echo $ex->getMessage();
				}
			}*/
			## FIN BREDEA




			############################## VIEW RENDERGIN LOC ########################

			$idResa = $resa ? $resa->id : 0;

			/*$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/locataire')
			->setVariables(array(
				   // 'form' => $locForm,
					//'isGoal' => $loc->codeGoal?1:0,
					'lang'=>'fr_FR',
					'extra'=>$this->getFormDynamique($idCampagne,$loc->id, $idResa,$params),
					//'libelles'=>$libelles,
					'isResaManuelle'=>$isResaManuelle,
			));

			$htmlOutputLoc = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);
			*/
			$timestartFirstForeach = microtime(true);

			$locParams = array('idCampagne' => $idCampagne, 'idLocataire' => $loc->id, 'idResa' => $idResa, 'params' => $params);
			$htmlOutputLoc = "";
			if ($call != "liste") {
				//on appele pas cette methode, puisque c deja fait dans l action edition
				$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheLocataire');
				if ($allowdCamp) {
					$htmlOutputLoc = $this->loadLocataireTab($locParams);
				} else {
					$htmlOutputLoc = $accesInterdit;
				}
			}


			$timeend = microtime(true);
			$execution_time = $timeend - $timestartFirstForeach;
			$page_load_time = number_format($execution_time, 3);
			//echo "loadLocataireTab in $page_load_time sec";

			############################## VIEW RENDERGIN RESA ########################

			/*$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/resa')
			->setVariables(array(
					'form' => $resaForm,
					'resa' => $resa,
					'historiqueResa' => $historiqueResa,
					'isGoal' => $loc->codeGoal?1:0,
					'lang'=>'fr_FR',
					'maxChoix' => $maxChoix,
					'idCampagne'=>$idCampagne,
			));

			$htmlOutputResa = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);*/
			$timestartFirstForeach = microtime(true);


			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheResa');
			if ($allowdCamp) {
				$htmlOutputResa = $this->loadReservationTab($resaParams);
			} else {
				$htmlOutputResa = $accesInterdit;
			}

			$timeend = microtime(true);
			$execution_time = $timeend - $timestartFirstForeach;
			$page_load_time = number_format($execution_time, 3);
			//echo "loadReservationTab in $page_load_time sec";

			############################## VIEW RENDERGIN COMPTE ########################


			$idResa = $resa ? $resa->id : 0;
			/*$comptesOld = array();

			//on verifie si  changement de site, et si l ancien dossier est archivé on l'affiche
			$reser = $this->getResaTable()->getResa($idResa);
			if($reser && $reser->idAncienneResa){
				$oldResa = $this->getResaTable()->getResa($reser->idAncienneResa);
				if($oldResa){
					//on verife si le dossir est archivé on l ajoute
					$dossierBredea = $this->lireDossierBredea($oldResa->id);
					if(!empty($dossierBredea) && $dossierBredea['dossi_trait'] != 'A'){
						$comptesOld = $this->loadComptes($oldResa->id);
					}

				}
			}

			$comptes = $this->loadComptes($idResa);
			if(!empty($comptesOld)){
				$comptes = array_merge($comptes,$comptesOld);
			}


			//$comptes = $this->getComptesTable()->fetchByLoc($idLocataire);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/compte')
			->setVariables(array(
					'isGoal' => $loc->codeGoal?1:0,
					'lang'=>'fr_FR',
					'comptes'=>$comptes,
			));

			$htmlOutputCompte = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);
			*/

			$htmlOutputIC = $htmlOutputCompte = "";
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheCompte');

			if ($idResa && $allowdCamp) {
				$htmlOutputCompte = $this->loadComptesTab($idResa);
			} else {
				$htmlOutputCompte = $accesInterdit;
			}

			############################## PARTIE MAIL #####################

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheMail');
			if ($allowdCamp) {
				$htmlOutputMail = $this->loadMailsTab($idLocataire);
			} else {
				$htmlOutputMail = $accesInterdit;
			}

			#####################################Documents###############################

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheDocuments');
			if ($allowdCamp) {
				$htmlOutputDocuments = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false), 'UTF-8', 'UTF-8');
			} else {
				$htmlOutputDocuments = $accesInterdit;
			}

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheEditionDocuments');
			if ($allowdCamp) {
				$htmlOutputEditionDocuments = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, true), 'UTF-8', 'UTF-8');
			} else {
				$htmlOutputEditionDocuments = $accesInterdit;
			}

			##################################INTER-CONTRAT###############################

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheIntercontrat');
			if ($resa && $allowdCamp) {
				$htmlOutputIC = $this->loadIntercontratTab($resa);
			} else {
				$htmlOutputIC = $accesInterdit;
			}

			####################################### PRELEVEMENT ######################################
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'fichePrelevements');
			if ($idResa && $allowdCamp) {
				$htmlOPPrelevement = $this->loadPrelevementTab($idResa);
			} else {
				$htmlOPPrelevement = $accesInterdit;
			}

			####################################### PAIEMENTEMAIL ######################################
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'fichePaiementEmail');
			if ($idResa && $allowdCamp) {
				$htmlOPPaiementEmail = $this->loadPaiementEmailTab($idResa);
			} else {
				$htmlOPPaiementEmail = $accesInterdit;
			}

			####################################### Logs ######################################
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheLogs');
			if ($idResa && $allowdCamp) {
				$htmlOPLogs = $this->loadLogsTab($idResa, 1);
			} else {
				$htmlOPLogs = $accesInterdit;
			}

			############################## TAB SMS #####################

			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheSMS');
			if ($allowdCamp) {
				$htmlOutputSMS = $this->loadSMSTab($idLocataire);
			} else {
				$htmlOutputSMS = $accesInterdit;
			}


			//$timeend = microtime(true);
			//$execution_time = $timeend - $timestart;
			//$page_load_time = number_format($execution_time, 3);
			//echo "<br>Traitements  execute en " . $page_load_time . " sec";exit();
			$htmlOutputEDL = "";
			$allowdCamp = $this->getTabsDroitParCampagne($idCampagne, 'ficheEDL');
			if ($idResa && $allowdCamp) {
				$htmlOutputEDL = $this->loadEDLTab($idResa, $idLocataire);
			}




			$view = new JsonModel(array(
						'success' => true,
						  'htmlOPLoc' => $htmlOutputLoc,
						'htmlOPResa' => $htmlOutputResa,
						'htmlOPCompte' => $htmlOutputCompte,
						'htmlOPMail' => $htmlOutputMail,
						'htmlOPDocuments' => $htmlOutputDocuments,
						'htmlOutputIC' => $htmlOutputIC,
						'htmlOPEditionDocuments' => $htmlOutputEditionDocuments,
						'titreFicheLocataire' => $titreFicheLocataire,
						'locataire' => $loc,
						'htmlOPPrelevement' => $htmlOPPrelevement,
						'htmlOPPaiementEmail' => $htmlOPPaiementEmail,
						'htmlOPLogs' => $htmlOPLogs,
						'htmlOPSMS' => $htmlOutputSMS,
						'htmlOPEDL' => $htmlOutputEDL,
						'allowedTabs' => $this->getAllAlowedTabsByCamp($idCampagne),
						//'debug'	=> $debug,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function lireDossierBredea($idResa)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$conf = $this->getConfigurationTable()->getConfig(1);
		$dossier = array();
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				if ($resa->numDossier) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					if ($resa && $resa->numDossier && $resa->codeSite) {
						$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
						$dossier = $bredea->lireDossier($cData);
					}

					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				//echo $ex->getMessage();
			}
		}
		return $dossier;
	}

	public function loadComptes($idResa, $mode = 0)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa mode=$mode");

		$conf = $this->getConfigurationTable()->getConfig(1);
		$comptes = $comptesCaution = $comptesWL = array();
		if (!$idResa) {
			return array('comptes' => $comptes, 'comptesCaution' => $comptesCaution);
		}
		$resa = $this->getResaTable()->getResa($idResa);

		$comptesRes = $this->getComptesTable()->fetchByLoc($resa->idLocataire);
		foreach ($comptesRes as $c) {
			if ($c->idReservation == $idResa) {
				$comptesWL[] = $c;
			}
		}
		$etatRemboursement = "";
		//on recupe la resa du locataire, si changement de site avant accueil
		$resaChgtSite = null;
		if ($resa->idAncienneResa) {
			$resaChgtSite = $this->getResaTable()->getResa($resa->idAncienneResa);
			if ($resaChgtSite->idAncienneResa) {
				$resaChgtSite = $this->getResaTable()->getResa($resaChgtSite->idAncienneResa);
			}
		}

		if ($conf && $conf->bredea == 1 && $this->pms && $this->pms->getClassName() == "Bredea") {
			## BREDEA
			try {
				##$bredea = new BredeaSql();
				$bredea = $this->pms;


				if ($resa && $resa->numDossier) {
					$comptes = array();
					//$residenceDuType = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);

					$codeSite = $resa->codeSite;

					$typre = $resa->typre ? $resa->typre : 'R';
					$typeSolde = $conf->typeSolde ? $conf->typeSolde : 'normal';
					$rData = array('codeSite' => $codeSite, 'numResa' => $resa->numResa, 'numDossier' => $resa->numDossier, 'typre' => $typre, 'typeSolde' => $typeSolde);

					if ($conf->modeFactureOuExtrait == 1 || $mode == 1) {
						$bredeaComptes = $bredea->lireExtraitCompte($rData);
					} else {
						$bredeaComptes = $bredea->lireCompteModeFacture($rData);
					}


					$factures = $bredeaComptes['facture'];
					$cautions = $bredeaComptes['caution'];
					$prets = $bredeaComptes['pret'];

					//on affiche la caution de l'ancienne résa si changement de site avant accueil
					if (empty($cautions) && $resaChgtSite && $resaChgtSite->numDossier) {
						$rData = array('codeSite' => $resaChgtSite->codeSite, 'numResa' => $resaChgtSite->numResa, 'numDossier' => $resaChgtSite->numDossier, 'typre' => $typre, 'typeSolde' => $typeSolde);
						if ($conf->modeFactureOuExtrait == 1 || $mode == 1) {
							$bredeaComptes = $bredea->lireExtraitCompte($rData);
						} else {
							$bredeaComptes = $bredea->lireCompteModeFacture($rData);
						}
						$cautions = $bredeaComptes['caution'];
					}


					/*foreach($factures as $f){
						$f->idReservation = $resa->id;
						$comptes[] = $f;
					}

					foreach($cautions as $c){
						$c->idReservation = $resa->id;
						$comptes[] = $c;
					}

					foreach($prets as $p){
						$p->idReservation = $resa->id;
						$comptes[] = $p;
					}*/

					$fraisPaye = false;
					foreach ($factures as $f) {
						$f->idReservation = ($resa->idNouvelleResa > 0 && !empty($resas[$resa->idNouvelleResa]) && $resas[$resa->idNouvelleResa]->numDossier != "") ? $resa->idNouvelleResa : $resa->id;
						$f->idLigneResa  = $resa->id;
						$comptes[] = $f;
						//si option et paiement manule des frais on demande pas de les paye,
						//on verifie si montant de la facture = montant frais initiaux
						if ($option && $montantFraix == $f->solde) {
							$fraisPaye = true;
						}


						/*if($f->idADP && in_array($f->idADP, $noFacts)){
						}else{
							$comptes[] = $f;
						}
						if($f->idADP){
							$noFacts[] = $f->idADP;
						}*/
					}

					//on cherche le solde caution, si = 0, on affiche aucun caution dans le premier onglet
					$totalCredit = $totalSolde = 0;
					foreach ($cautions as $c) {
						$totalCredit += $c->credit;
						$totalSolde += $c->solde;
					}

					//on verife si option et caution paye
					if ($option && $montantCaution == $totalCredit && $fraisPaye) {
						$option = false;
					}

					foreach ($cautions as $c) {
						$c->idReservation = $resa->idNouvelleResa > 0 ? $resa->idNouvelleResa : $resa->id;
						if ($totalCredit != $totalSolde) {
							//$comptes[] = $c;
						}

						//on cherche si il ya un caution à rembourser
						$rmb = $this->getTableObjet('remboursements')->select(array('idReservation' => $resa->id, 'idLocataire' => $resa->idLocataire))->current();
						if ($rmb && $rmb->noOD == $c->idADP) {
							$c->etat = $rmb->etatDG;
							$etatRemboursement = $rmb->etatDG;
							if ($rmb->etatDG == 4) {
								//rembourser, on mis virement du date
								$c->nature = "Virement du ".str_replace('-', '/', $c->dateFacture);
							}
						}
						$comptesCaution[] = $c;

						/*if($c->idADP && in_array($c->idADP, $noFacts)){
						}else{
							$comptes[] = $c;
						}
						if($c->idADP){
							$noFacts[] = $c->idADP;
						}*/
					}


					foreach ($prets as $p) {
						$p->idReservation = $resa->idNouvelleResa > 0 ? $resa->idNouvelleResa : $resa->id;
						$comptes[] = $p;
						/*if($p->idADP && in_array($p->idADP, $noFacts)){
						}else{
							$comptes[] = $p;
						}
						if($p->idADP){
							$noFacts[] = $p->idADP;
						}*/
					}
				}//end if numDossier

				$bredea->closeConnect();
				$this->pms	= null;

				if (!$resa->numDossier) {
					$comptes = $comptesWL;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".". __LINE__.".". " idResa=$idResa idApiPms=$idApiPms NO_SEJOUR=$NO_SEJOUR Bredea : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		} elseif ($conf && $conf->bredea == 1 && $this->pms && $this->pms->getClassName() === "CeriFoyer") {
			## Ceri-Foyer
			## ~~~~~~~~~~
			$NO_SEJOUR	= $resa->idPMS;
			try {
				list($comptes, $comptesCaution, $fraisInitiaux)	= $this->pms->lireCompte($resa, $mode);
			} catch (Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__, __LINE__, " idResa=$idResa idApiPms=$idApiPms NO_SEJOUR=$NO_SEJOUR CeriFoyer : Exception=".$ex->getMessage());
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa NO_SEJOUR=$NO_SEJOUR nbComptes=".count($comptes)." nbComptesCaution=".count($comptesCaution)." nbFraisInitiaux=".count($fraisInitiaux));
		}

		return array('comptes' => $comptes, 'comptesCaution' => $comptesCaution, 'fraisInitiaux' => $fraisInitiaux);
	}

	public function loadmodelecturecompteAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$modeLectureCompte = (int)$request->getPost('modeLectureCompte');

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa modeLectureCompte=$modeLectureCompte");
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

			$comptesOld = array();
			//on verifie si  changement de site, et si l ancien dossier est archivé on l'affiche
			$resa = $this->getResaTable()->getResaWithPms($idResa);
			if ($resa && $resa->idAncienneResa) {
				$oldResa = $this->getResaTable()->getResaWithPms($resa->idAncienneResa);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa oldIdResa=".$resa->idAncienneResa);
				if ($oldResa && ($idApiPms = $oldResa->idApiPms)) {
					## Connexion au PMS
					## ~~~~~~~~~~~~~~~~
					try {
						$pmsGen	= new PmsGen($adapter, $idApiPms);
						if ($pmsGen) {
							$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
							if (is_object($pms)) {
								$this->pms	= $pms;
							}
						}
						if ($this->pms) {
							if ($this->pms->getClassName() === "Bredea") {
								//on verife si le dossir est archivé on l ajoute
								$dossierBredea = $this->lireDossierBredea($oldResa->id);
								if (!empty($dossierBredea) && $dossierBredea['dossi_trait'] != 'A') {
									$return = $this->loadComptes($oldResa->id, $modeLectureCompte);
									$comptesOld = $return['comptes'];
								}
							}
						} else {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms injoignable");
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
					}
				}
			}

			$idApiPms	= $resa->idApiPms;
			if (!is_object($this->pms) || $idApiPms != $this->pms->getIdApiPms()) {
				if ($idApiPms) {
					## Connexion au PMS
					## ~~~~~~~~~~~~~~~~
					try {
						$this->pms	= null;
						$pmsGen	= new PmsGen($adapter, $resa->idApiPms);

						if ($pmsGen) {
							$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
							if (is_object($pms)) {
								$this->pms	= $pms;
							}
						}
						if (!$this->pms) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms injoignable");
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
					}
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms idApiPms_fromPMS=".($this->pms ? $this->pms->getIdApiPms() : "non transmis"));

			$return = $this->loadComptes($idResa, $modeLectureCompte);
			$comptes = $return['comptes'];
			$comptesCaution = $return['comptesCaution'];
			$fraisInitiaux = $return['fraisInitiaux'];
			if (!empty($comptesOld)) {
				$comptes = array_merge($comptes, $comptesOld);
			}

			$prestations = array();
			$presResult = $this->getTableObjet('type_prestation')->select();
			foreach ($presResult as $p) {
				$prestations[$p->id] = $p->type;
			}

			## on cherche les modeles de docs existant, pour afficher que ceux qu'on
			$tools = new Tools();
			$modelesDocsExists = array();
			$modelesDocs = $this->getTableObjet('type_modeles_docs')->select(array('active' => '1', 'typeModele' => 'reservation'));
			foreach ($modelesDocs as $m) {
				if (is_dir(getcwd()."/public/docs/modeles/".$m->code)) {
					$modFiles = $tools->lireDocumentsDeRepertoire(getcwd()."/public/docs/modeles/".$m->code);
					if (!empty($modFiles)) {
						$modelesDocsExists[$m->id] = $m->code;
					}
				}
			}


			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/compte')
			->setVariables(array(
					'lang' => 'fr_FR',
					'comptes' => $comptes,
					'mode' => $modeLectureCompte,
					'comptesCaution' => $comptesCaution,
					'fraisInitiaux' => $fraisInitiaux,
					'config' => $conf,
					'prestations' => $prestations,
					'docTable' => $this->getDocumentTable(),
					'modelesDocsExists' => $modelesDocsExists,

			));

			$htmlOutputCompte = $this->getServiceLocator()
								->get('viewrenderer')
								->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOutputCompte,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function autosearchAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$keyword = $request->getPost('keyword');

			$tableLocObj = $this->getTableObjet('locataires');
			$select = $tableLocObj->getSql()->select();
			$select->where->like('nom', "$keyword%");
			//$select->where(array('archive'=>'0'));
			$select->order(array('nom ASC'));
			$rows = $tableLocObj->selectWith($select);
			$htmlOutput = "";
			foreach ($rows as $row) {
				$htmlOutput .= "<p data-id='".$row->id."' data-requestRunning=''>".$row->nom.' '.$row->prenom."</p>";
			}
			if ($htmlOutput == "") {
				$htmlOutput = "<p data-requestRunning=''>Aucun</p>";
			}


			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function loadlocataireAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idLocataire = $request->getPost('idLocataire');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			$idLogement = $request->getPost('idLogement');

			//on recupere la campage fixe
			$campFixe = $this->getTableObjet('campagnes')->select(array('fixe' => 1))->current();
			$idCampagne = $campFixe ? $campFixe->id : 0;

			$params = array();
			$params['dateArrivee'] =  $dateDebut;
			$params['dateDepart'] =  $dateFin;
			$params['idLogement'] =  $idLogement;

			$charger = false;
			$htmlOutput = "";
			if ($dateDebut && $dateFin && $idLogement) {
				$charger = true;
				$htmlOutput = $this->getFormDynamique($idCampagne, $idLocataire, 0, 0, $params);
			}


			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,
						  'charger' => $charger,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	private function getHistoriqueResa($resa, $return = array())
	{
		$historiqueResa = $return;
		if ($resa->idAncienneResa > 0) {
			$ancienneResa = $this->getResaTable()->getResa($resa->idAncienneResa);
			if ($ancienneResa && $ancienneResa->idLogement) {
				$ancienLogement = $this->getLogementTable()->getLogement($ancienneResa->idLogement);

				$idAncienTypeLogement = $ancienneResa->idTypeLogementAttribue;
				if (!$idAncienTypeLogement) {
					$idAncienTypeLogement = $ancienLogement->idTypeLogement;
				}
				$ancienTypeLogement = $this->getTypelogementTable()->getTypeLogement($idAncienTypeLogement);

				$programme = $this->getProgrammeTable()->getProgrammeById($ancienneResa->idProgramme);
				$sousProgramme = $programme;
				if ($ancienneResa->idSousProgramme) {
					$sousProgramme = $this->getProgrammeTable()->getProgrammeById($ancienneResa->idSousProgramme);
				}

				$historiqueResa[] = array(
									'logement' => $ancienLogement,
									'typeLogement' => $ancienTypeLogement,
									'arrivee' => date('Y', strtotime($ancienneResa->dateArrivee)) > 2000 ? date('d-m-Y', strtotime($ancienneResa->dateArrivee)) : "",
									'depart' => date('Y', strtotime($ancienneResa->dateDepart)) > 2000 ? date('d-m-Y', strtotime($ancienneResa->dateDepart)) : "",
									'programme' => $programme ? $programme->nom : "",
									'sousProgramme' => $sousProgramme ? $sousProgramme->nom : "",
									);
				//appel recursive
				if ($ancienneResa->idAncienneResa > 0) {
					$historiqueResa = $this->getHistoriqueResa($ancienneResa, $historiqueResa);
				}
			}
		} elseif ($resa->idNouvelleResa > 0) {
			$nouvelleResa = $this->getResaTable()->getResa($resa->idNouvelleResa);
			if ($nouvelleResa && $nouvelleResa->idLogement) {
				$ancienLogement = $this->getLogementTable()->getLogement($nouvelleResa->idLogement);

				$idAncienTypeLogement = $nouvelleResa->idTypeLogementAttribue;
				if (!$idAncienTypeLogement) {
					$idAncienTypeLogement = $ancienLogement->idTypeLogement;
				}
				$ancienTypeLogement = $this->getTypelogementTable()->getTypeLogement($idAncienTypeLogement);

				$programme = $this->getProgrammeTable()->getProgrammeById($nouvelleResa->idProgramme);
				$sousProgramme = $programme;
				if ($nouvelleResa->idSousProgramme) {
					$sousProgramme = $this->getProgrammeTable()->getProgrammeById($nouvelleResa->idSousProgramme);
				}

				$historiqueResa[] = array(
									'logement' => $ancienLogement,
									'typeLogement' => $ancienTypeLogement,
									'arrivee' => date('Y', strtotime($nouvelleResa->dateArrivee)) > 2000 ? date('d-m-Y', strtotime($nouvelleResa->dateArrivee)) : "",
									'depart' => date('Y', strtotime($nouvelleResa->dateDepart)) > 2000 ? date('d-m-Y', strtotime($nouvelleResa->dateDepart)) : "",
									'programme' => $programme ? $programme->nom : "",
									'sousProgramme' => $sousProgramme ? $sousProgramme->nom : "",
									);
				//appel recursive
				if ($nouvelleResa->idNouvelleResa > 0) {
					$historiqueResa = $this->getHistoriqueResa($nouvelleResa, $historiqueResa);
				}
			}
		}

		return $historiqueResa;
	}

	private function getChampsDeBaseByCampagneLibelle($idCampagne)
	{
		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$formulaires = $this->getTableObjet('formulaires')->select(array('idCampagne' => $idCampagne, 'active' => 1));
		$libIds = array();
		foreach ($formulaires as $formRow) {
			$champs = $this->getChampsFormulaireTable()->select(array('idFormulaire' => $formRow->id, 'active' => 1));
			foreach ($champs as $champ) {
				$lmsgid = 'l_'.$champ->name.'_'.$champ->id;
				$libIds[$champ->name] = $lmsgid;
			}
		}
		return $libIds;
	}


	public function getFormDynamique($idCampagne, $idLocataire = 0, $idResa = 0, $idDp = 0, $params = array(), $idProfile = 0)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa idDp=$idDp idCampagne=$idCampagne");
		if (!$idCampagne) {
			return "";
		}

		$gestId = 1;
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$campagneType = $this->getCampagneTable()->getCampagneType($idCampagne);

		$tools =  new Tools();

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$translator->setLocale('fr_FR');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		//recup infos resa à dupliquer
		$idResaADupliquer = null;
		$memeUsager = 0;
		if (!empty($params['idResaADupliquer']) && $params['idResaADupliquer'] > 0) {
			$r = $this->getTableObjet('reservations')->select(array('id' => $params['idResaADupliquer']))->current();
			if ($r) {
				$idResa = $r->id;
				$idLocataire = $r->idLocataire;
				$idResaADupliquer = $params['idResaADupliquer'];
				$memeUsager = $params['memeUsager'];
			}
		}
		## création nouveau dossier :
		$creationNouveauDossier = '';
		if (!empty($params['nouveauDossier']) && $params['nouveauDossier'] == true) {
			$creationNouveauDossier = 1;
		}
		//récup champs financier
		$champsFinancier = $this->getFinancierTable()->getChampsFinancier();

		$idOngletFormulaire = !empty($params['idOnglet']) ? $params['idOnglet'] : null;
		$isMembreMenage = !empty($params['isMembreMenage']) ? $params['isMembreMenage'] : null;
		if ($isMembreMenage) {
			$idOngletFormulaire = -1;
		}//si on charge le detail d'un membre de ménage depsui l'onglet Memebre famille, on affiche tout les formulaire

		$loc = null;
		if ($idLocataire) {
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
			//return "Locataire introuvable";
		}
		//print_r($idLocataire);exit();

		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa idDp=$idDp idProfile=$idProfile");

		$idSousProgramme = "";
		$idProgramme = $loc->idProgramme;
		$locAllInfosObj = array();
		if ($loc) {
			$idSousProgramme = $loc->idSousProgramme ? $loc->idSousProgramme : $loc->idProgramme;
			$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($loc->id, $adapter, $idResa, $idDp);
			//on check la date de naissance4
			$formatDT = "Y-m-d";
			$dt = \DateTime::createFromFormat($formatDT, $loc->dateNaissance);

			if (/*strtotime($loc->dateNaissance) == strtotime("1970-01-01") ||*/ !$loc->dateNaissance || ($dt && $dt->format($formatDT) != $loc->dateNaissance)) {
				$loc->dateNaissance = "";
				$locAllInfosObj['dateNaissance'] = "";
				$locAllInfosObj['age'] = "";
			}
			$locAllInfosObj['idUsager'] = $loc->id;
		}

		//on verifie si le type locataire est active(au moins un active => activé)
		$typesLoc = $this->getTableObjet('type_locataires')->select(array('active' => 1));
		$controleTypeLocataire = false;
		if ($typesLoc->count() > 0) {
			$controleTypeLocataire = true;
		}


		//si on cree une resa manuel, on cherche le programme et sp  lie a cette campagne
		$couleurAccordion = "";
		if (!empty($params)) {
			$progsDeCamp = $this->getProgrammeTable()->getProgrammesParentDeCampagnes(array($idCampagne))->current();
			if ($progsDeCamp) {
				$idProgramme = $idSousProgramme = $progsDeCamp->id;
				//on cherche le sp
				$spCamp = $this->getProgrammeTable()->getSousProgrammes($progsDeCamp->id)->current();
				if ($spCamp) {
					$idSousProgramme = $spCamp->id;
				}
			}
			//on recupere le type logement du logement choisi
			if (!empty($params['idLogement'])) {
				$log = $this->getLogementTable()->getLogement($params['idLogement']);
				if ($log) {
					$params['idTypeLogement1'] = $log->idTypeLogement;
				}
			}
			if (!empty($params['couleurAccordion'])) {
				$couleurAccordion = $params['couleurAccordion'];
			}
		}

		$idProgramme = $loc->idProgramme;

		if ($idResa) {
			$resa = $this->getResaTable()->getResa($idResa);
			if ($resa) {
				//on prend le programme et sou programme de la résa
				if ($resa->idProgramme) {
					$idProgramme = $resa->idProgramme;
					$loc->idProgramme = $idProgramme;
					$locAllInfosObj['idProgramme'] = $idProgramme;
				}
				if ($resa->idSousProgramme) {
					$idSousProgramme = $resa->idSousProgramme;
					$loc->idSousProgramme = $idSousProgramme;
					$locAllInfosObj['idSousProgramme'] = $idSousProgramme;
				}
				$locAllInfosObj['idReservationUsager'] = $idResa;
				$resaArray = get_object_vars($resa);
				foreach ($resaArray as $k => $v) {
					if (!$v || $v == "") {
						unset($resaArray[$k]);
					}
				}
				$locAllInfosObj = array_merge($locAllInfosObj, $resaArray);
				$locAllInfosObj['dateArrivee'] = $resa->dateArrivee && $resa->dateArrivee != "0000-00-00" ? date('d-m-Y', strtotime($resa->dateArrivee)) : "";
				$locAllInfosObj['dateDepart'] = $resa->dateDepart && $resa->dateDepart != "0000-00-00" ? date('d-m-Y', strtotime($resa->dateDepart)) : "";
				$locAllInfosObj['residenceOrientation'] = $resa->residenceOrientation ? $resa->residenceOrientation : "";

				## ajout ressource entree
				$ressource = $this->getPLAITable()->getRessourcesDeResa($idResa);
				if ($ressource) {
					$locAllInfosObj['ressEntree'] = $ressource['ressEntree'];
					$locAllInfosObj['nbrPersEntree'] = $ressource['nbrPersEntree'];
					$locAllInfosObj['nbrPersChargeEntree'] = $ressource['nbrPersChargeEntree'];
					$locAllInfosObj['handicapEntree'] = $ressource['handicapEntree'];
					$locAllInfosObj['finValiditeHandicapEntree'] = $ressource['finValiditeHandicapEntree'];
					$locAllInfosObj['preuveHandicapEntree'] = $ressource['preuveHandicapEntree'];
					$locAllInfosObj['statutDoc_preuveHandicapEntree'] = $ressource['statutPreuveHandicapEntree'];
					$locAllInfosObj['finValidite_preuveHandicapEntree'] = $ressource['finValiditeHandicapEntree'];
				}

				## Ajout champs financier
				$financier = $this->getFinancierTable()->getFinancierDeResa($idResa);
				if ($financier) {
					if (!is_array($financier)) {
						$financier = get_object_vars($financier);
					}
					$locAllInfosObj = array_merge($locAllInfosObj, $financier);
				}
				## recup statut attestation assurance et date fin assurance
				if ($resa->statutAssur) {
					$locAllInfosObj['statutDoc_certificatAssur'] = $resa->statutAssur;
				}
				if ($resa->dateFinAssur) {
					$locAllInfosObj['finValidite_certificatAssur'] = $resa->dateFinAssur;
				}

				## Ajout champs SEPA
				$sepa = $this->getSEPATable()->getChampsDeResa($idResa, $resa->idLocataire);
				if($sepa) {
					$locAllInfosObj['prelevementSEPA'] = $sepa['prelevementSEPA'];
					$locAllInfosObj['jourPrelevementSEPA'] = $sepa['jourPrelevementSEPA'];
					$locAllInfosObj['typePrelevementSEPA'] = $sepa['typePrelevementSEPA'];
					$locAllInfosObj['montantPrelevementSEPA'] = $sepa['montantPrelevementSEPA'];
					$locAllInfosObj['mandatSEPA'] = $sepa['mandatSEPA'];
					$locAllInfosObj['statutDoc_mandatSEPA'] = $sepa['statutDoc_mandatSEPA'];
					$locAllInfosObj['finValidite_mandatSEPA'] = $sepa['finValidite_mandatSEPA'];
					$locAllInfosObj['ibanSEPA'] = $sepa['ibanSEPA'];
					$locAllInfosObj['bicSEPA'] = $sepa['bicSEPA'];
					$locAllInfosObj['domiciliationSEPA'] = $sepa['domiciliationSEPA'];
					$locAllInfosObj['dateMandatSEPA'] = $sepa['dateMandatSEPA'];
					$locAllInfosObj['rumSEPA'] = $sepa['rumSEPA'];
				}

				//ajout choix type logement
				$choixRow = $this->getChoixTable()->fetchBy(array('idReservation' => $idResa,
													'numeroChoix' => 1,
													))->current();
				if($choixRow) {
					$locAllInfosObj['idTypeLogement'] = $choixRow->idTypeLogement;
				}

			}
		}
		if ($idDp) {
			//$dp = $this->getTableObjet('domiciliations')->select(array('id'=>$idDp))->current();
			$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			$locAllInfosObj['dateEntree'] = $dp->dateEntree;
			$locAllInfosObj['dateSortie'] = $dp->dateSortie;
			$locAllInfosObj['etat'] = $dp->etat;
		}

		if ($idResaADupliquer > 0) {
			if(!$memeUsager) {
				$idLocataire = 0;
			}
			$idResa = 0;
			$resa = null;
			if(!$memeUsager) {
				$loc = null;
			}
			if(!$memeUsager) {
				unset($locAllInfosObj['id']);
			}
			if(!$memeUsager) {
				unset($locAllInfosObj['idLocataire']);
			}
			unset($locAllInfosObj['idReservation']);
			unset($locAllInfosObj['idLogement']);
			unset($locAllInfosObj['numeroChambre']);
			unset($locAllInfosObj['idAncienneResa']);
			unset($locAllInfosObj['idNouvelleResa']);
			unset($locAllInfosObj['flag']);
		}


		$langue = "fr_FR";

		$session = new Container('formulaire');
		$session->idLocataire = $idLocataire;

		$sessData = $locAllInfosObj;

		$idCamp = $idCampagne;
		$modeCampagne = $this->getCampagneTable()->getCampagneMode($idCampagne);

		$champsDeCriteres = array();

		if ($conf->modeRecupProgCampagne == 'idProgramme') {
			$progamme = $this->getProgrammeTable()->getProgrammeDeCampagneEnCours($idProgramme, $idCamp);
		} else {
			$progamme = $this->getProgrammeTable()->getProgrammeDeCampagneEnCours($idSousProgramme, $idCamp);
		}


		//recup de la residence via la campagne
		$residenceDeCampagne = $this->getResidencesTable()->getResidenceDeCampagne($idCamp);


		$residenceDeLogement = null;
		//recup de logement
		if (!empty($sessData['idLogement'])) {
			$logeRow = $this->getTableObjet('logements')->select(array('id' => $sessData['idLogement']))->current();
			if ($logeRow) {
				$sessData['logeVille'] = $locAllInfosObj['logeVille'] = $logeRow->logeVille;
				$sessData['logeCP'] = $locAllInfosObj['logeCP'] = $logeRow->logeCP;
				$residenceDeLogement = $this->getLogementTable()->getResidenceDeLogement($logeRow->id);
			}
		}

		## récup type logement attribue
		if (!empty($sessData['idTypeLogementAttribue'])) {
			$typeLoge = $this->getTableObjet('type_logement')->select(array('id' => $sessData['idTypeLogementAttribue']))->current();
			if ($typeLoge) {
				$sessData['typeLogementAttribue'] = $locAllInfosObj['typeLogementAttribue'] = $typeLoge->nom;
			}
		}

		$residenceOrientation = null;
		if (!empty($sessData['residenceOrientation'])) {
			$residenceOrientation = $this->getResidencesTable()->getResidence($sessData['residenceOrientation']);
		}

		## Résidence logement
		if ($residenceDeLogement && !$residenceOrientation) {
			$sessData['residenceOrientation'] = $residenceDeLogement->idResidence;
			$locAllInfosObj['residenceOrientation'] = $residenceDeLogement->idResidence;
		}

		//$typesLogRes =  $this->getTypelogementTable()->fetchByProgramme($idSousProgramme, $idCamp);
		$typesLogRes =  $this->getTypelogementTable()->fetchAllWithTarif($group = true);
		$typesLog = array();
		$typesLogIds = array();

		$tarifsTable = $this->getTable("tarifs");
		$tarifsValeurChampsTable = $this->getTable("tarifs_valeurs_champs");

		foreach ($typesLogRes as $t) {
			$typesLog[] = $t;
			$typesLogIds[] = $t->id;

			//criteres de tarifs
			$tarifsDetype = $tarifsTable->select(array('idTypeLogement' => $t->id, 'idCampagne' => $idCamp));
			foreach ($tarifsDetype as $tarif) {
				$criteres = $tarifsValeurChampsTable->select(array('idTarif' => $tarif->id));
				foreach ($criteres as $c) {
					if ($c->idChamp > 0) {
						$champ = $this->getChampsFormTable()->select(array('id' => $c->idChamp))->current();
						$champsDeCriteres[$champ->id] = $champ;//pour la verification au cas de changement de valeur
					} else {
						$champDebut = $this->getChampsFormTable()->select(array('id' => $c->champDebut))->current();
						$champFin = $this->getChampsFormTable()->select(array('id' => $c->champFin))->current();

						$champsDeCriteres[$champDebut->id] = $champDebut;
						$champsDeCriteres[$champFin->id] = $champFin;
					}
				}
			}
		}


		## nombre de choix de type logement
		if ($conf->modeRecupProgCampagne == 'idProgramme') {
			$choixRow = $this->getProgrammeTable()->getProgrammeDeCampagneEnCours($loc->idProgramme, $idCamp);
		} else {
			$choixRow = $this->getProgrammeTable()->getProgrammeDeCampagneEnCours($idSousProgramme, $idCamp);
		}
		//print_r($choixRow);exit();
		$minChoix = $maxChoix = 1;

		if ($choixRow) {
			$minChoix = $choixRow->minChoix ? $choixRow->minChoix : 0;
			$maxChoix = $choixRow->maxChoix ? $choixRow->maxChoix : 1;
		}
		## ordre de choix
		$modeChoixTL = $this->getTable('mode_choix_logement')->select(array('idCampagne' => $idCamp))->current();
		$modeChoix = $ordreChoix = null;
		if ($modeChoixTL) {
			$modeChoix = $modeChoixTL->modeChoix;
			$ordreChoix = $modeChoixTL->ordreChoix;
		}

		$formsArray = array();
		$formsAllFields = array();
		$formsCols = array();
		$formsDateFields = array();
		$formulaires = array();
		$formNumRows = array();

		$docsFields = array();
		$emptyOption = "";
		$typesLogement = array();

		$formActions = array();
		$datesPlage = array();

		//pour les categories documents
		$formsCatDocs = $formsSuivis = array();


		## Identification des champs liés aux actions pour ne vérifier que ceux-là
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$idsChampsActions = $this->getChampsLiesAuxActions($idCampagne);

		syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa countIdsChampsActions=".count($idsChampsActions)." idsChampsActions=".json_encode($idsChampsActions));

		// echo "<pre> ligne 7481";
		// var_dump($idsChampsActions);
		// echo "</pre>";
		// die();

		## Lecture de tous les champs des formulaires pour cette campagne
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$forms = $this->getFormulaireTableModel()->getAllBOForms($idCampagne, $idProfile, $idOngletFormulaire);
		// $forms = $this->getFormulaireTableModel()->getAllBOForms($idCampagne,$idProfile,$idOngletFormulaire);
		if ($forms->count() == 0) {
			return "";
		}
		//recup de tout ls champs de la campagne
		$sql	= $this->getChampsFormulaireTable()->getSql();
		$select	= $sql->select();
		$select->join('formulaires', 'formulaires.id = champs_formulaires.idFormulaire', array('idForm' => 'id'));
		$select->join('champs_suivis', 'champs_suivis.id = champs_formulaires.idChampSuivis', array('idCS' => 'id', 'idTypeSuivis'), 'LEFT');
		$select->where(array('formulaires.idType' => '1', 'formulaires.idCampagne' => $idCampagne, 'champs_formulaires.active' => 1));
		$select->order(array('champs_formulaires.row', 'champs_formulaires.column'));
		## syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idCampagne=$idCampagne sql=".$sql->getSqlstringForSqlObject($select));
		$champsResult = $this->getChampsFormulaireTable()->selectWith($select);
		$champsFormulaire = array();
		foreach ($champsResult as $cr) {
			$champsFormulaire['byId'][$cr->id]			= $cr;
			$champsFormulaire['byForm'][$cr->idFormulaire][]	= $cr->id;
			$champsFormulaire['byName'][$cr->name]			= $cr->id;
			//on save les champs dupliquer, celui de base avec ces copies
			if ($cr->idParent > 0) {
				$champsFormulaire['byParent'][$cr->idParent][]	= $cr->id;
			}
			//champs suivis par type suivis
			if ($cr->idChampSuivis > 0) {
				$champsFormulaire['byTypeSuivis'][$cr->idTypeSuivis][] = $cr;
			}
		}
		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa idCampagne=$idCampagne modeChoix=$modeChoix ordreChoix=$ordreChoix count_champsFormulaire=".count($champsFormulaire['byId']));
		##syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa first_champsFormulaireById=".json_encode(array_slice($champsFormulaire['byId'], 0, 1)));
		##syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa champsFormulaireByForm=".json_encode($champsFormulaire['byForm']));
		syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa champsFormulaireByName=".json_encode($champsFormulaire['byName']));

		$champsSuivis = array();
		if (!empty($champsFormulaire['byTypeSuivis'])) {
			foreach ($champsFormulaire['byTypeSuivis'] as $idTypeSuivis => $champs) {
				foreach ($champs as $champ) {
					$champsSuivis[$champ->equivalentSql] = array(	'dyn' => 1,
													'typeField' => '',
													'idTypeHtml' => $champ->idType,
													'table' => 'champs_suivis',
													'idChamp' => $champ->idChampSuivis,
													'equivalentSql' => $champ->equivalentSql,
													'sourceListe' => $champ->sourceListe,
													'champ' => $champ,
													'idTypeSuivis' => $idTypeSuivis,
													);
				}
			}
			//on récup les valeurs des champs suivis
			$rowsData = array();
			if ($idResa) {
				$where = array();
				array_push($where, "reservations.id = $idResa");
				$rowsData = $this->getResaTable()->getListeWithAllFields($adapter, 0, $champsSuivis, $where, array('config' => $conf, 'callFrom' => 'ficheUsager'));
			} elseif ($idDp) {
				$where = array();
				array_push($where, "domiciliations.id = $idDp");
				$rowsData = $this->getDomiciliationsTable()->getAllDpFields($adapter, 0, $champsSuivis, $where, array('config' => $conf, 'fetchMode' => 'oneRow', 'idDp' => $idDp, 'callFrom' => 'ficheUsager'));
			}
			if (!empty($rowsData) && !empty($rowsData[0])) {
				$dataSuivis = $rowsData[0];
				if (array_key_exists('idCampagne', $dataSuivis)) {
					unset($dataSuivis['idCampagne']);
				}
				if (array_key_exists('idEtatResa', $dataSuivis)) {
					unset($dataSuivis['idEtatResa']);
				}
				if (array_key_exists('idResidenceOrientation', $dataSuivis)) {
					unset($dataSuivis['idResidenceOrientation']);
				}
				if (array_key_exists('idResidence', $dataSuivis)) {
					unset($dataSuivis['idResidence']);
				}
				$locAllInfosObj = $this->mergeData($locAllInfosObj, $dataSuivis);
			}
		}

		### fusion bredea infos locataire
		$returnGetReservationPms	= array();
		if (!empty($locAllInfosObj)) {
			$format = "Y-m-d";
			//fusion Bredea
			if ($idResa) {
				$returnGetReservationPms =  $this->getReservationPms($idResa);

				// var_dump("7278");
				// var_dump($returnGetReservationPms['loc']);die();

				if (!empty($returnGetReservationPms) && !empty($returnGetReservationPms['locArray'])) {
					$locArray = $returnGetReservationPms['locArray'];

					//on prend la ville WL si existe
					if ($locAllInfosObj['ville']) {
						unset($locArray['ville']);
					}

					//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa locArray=".json_encode($locArray));
					//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa locBredea=".json_encode($returnGetReservationPms));
					//on merge les infos WL et Bredea
					$locAllInfosObj = $this->mergeData($locAllInfosObj, $locArray);
				}
			}

			foreach ($locAllInfosObj as $key => $value) {
				$d = \DateTime::createFromFormat($format, $value);
				if ($d && $d->format($format) == $value) {
					if ($langue == 'fr_FR') {
						$locAllInfosObj[$key] = date('d-m-Y', strtotime($value));
					}
				}
			}
			//langue
			if (!empty($locAllInfosObj['langue'])) {
				## Provisoire car trop bétonné sur l'ordre FR/UK/ES
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($locAllInfosObj['langue'] == 'UK') {
					$locAllInfosObj['langue'] = 1;
				} elseif ($locAllInfosObj['langue'] == 'ES') {
					$locAllInfosObj['langue'] = 2;
				} else {
					$locAllInfosObj['langue'] = 0;
				}
			}

			// Type d'accès au logement
			if (!empty($locAllInfosObj['typeAccesLoge']) && $locAllInfosObj['typeAccesLoge'] != "" && !is_null($locAllInfosObj['typeAccesLoge'])) {
				$locAllInfosObj['typeAccesLoge'] = trim(strtolower($locAllInfosObj['typeAccesLoge'])) == 'mobile' ? 1 : 0;
			} else {
				$logement = $this->getTableObjet('logements')->select(array('id' => $locAllInfosObj['idLogement']))->current();
				$bat = $this->getTableObjet('batiments')->select(array('id' => $logement->idBatiment))->current();
				$residence = $this->getTableObjet('residences')->select(array('id' => $bat->idResidence))->current();
				$locAllInfosObj['typeAccesLoge'] = trim(strtolower($residence->typeAccesLoge)) == 'mobile' ? 1 : 0;
			}
		}
		###
		syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : locAllInfosObj=".json_encode($locAllInfosObj));

		//action oncheck, pour les valeur checked par defaut
		$champsAttacheeChecked = array();
		$champsAttacheToHide = array();
		$champsActionsParCondition = array('hide' => array(), 'show' => array());//on y stock les champs qui confirme des condition


		//on verife les action declancher par le formulaire d'identification
		$typeChampsTable = $this->getTable('type_champs_formulaire');
		$identificationForm = $this->getFormulaireTableModel()->getFrontFormBy(array('idCampagne' => $idCamp, 'idType' => 2))->current();
		if ($identificationForm) {
			syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions Identification Deb");
			$champsIdentification = $this->getTableObjet('champs_creationcompte')->select(array('idFormulaire' => $identificationForm->id));
			foreach ($champsIdentification as $ci) {
				$champ = $this->getChampsTable()->getChampActive($ci->idChamp);

				if (!in_array($champ->id, $idsChampsActions)) {
					continue;
				}
				$type = $typeChampsTable->select(array('id' => $champ->idType))->current();


				if ($type->type == "Checkbox" || $type->type == "Radio") {
					$actions = $this->getActionsjsTable()->select(array('idChamp' => $champ->id));

					$valeurCheck = "";
					if(!empty($locAllInfosObj[$champ->equivalentSql])) {
						$valeurCheck = $locAllInfosObj[$champ->equivalentSql];
					} elseif($champ->valeurParDefaut) {
						$valeurCheck = $champ->valeurParDefaut;
					}
					foreach ($actions as $action) {
						$champAttache = $this->getChampsFormTable()->select(array('id' => $action->idChampAttache))->current();

						if ($valeurCheck) {
							$champsAttacheeChecked[] = $champAttache->equivalentSql;
						}
						if ($valeurCheck && $action->valeur == 0) {
							$champsAttacheToHide[] = $champAttache->equivalentSql;
						}
					}
				}



				$dataActions = $locAllInfosObj;
				$dataActions['idCampagne'] = $idCamp;
				$dataActions['currentField'] = $champ->equivalentSql;
				$dataActions['idTypeLocataire'] = $resa ? $resa->idTypeLocataire : null;
				$dataActions['idResa'] = $resa ? $resa->idResa : null;
				$returnActions = $this->loadActions($dataActions, $champsFormulaire);
				syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId champName=$champName nb_returnActions=".count($returnActions['actionResult']));

				if (!empty($returnActions['actionResult'])) {
					$acRows = $returnActions['actionResult'];

					foreach ($acRows as $acRow) {
						$ac = $acRow['action'];
						$chAc = $acRow['champ'];
						syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId currField=$currField : action=$ac champ=".$chAc->id);
						if ($ac == "show") {
							//$champsActionsParCondition['show'][] = $chAc->equivalentSql;
							if (!in_array($chAc->id, $champsActionsParCondition['show'])) {
								$champsActionsParCondition['show'][] = $chAc->id;
								//on applique le resultat sur les champs enfants
								if (!empty($champsFormulaire['byParent'][$chAc->id])) {
									$champEnfants = $champsFormulaire['byParent'][$chAc->id];
									foreach ($champEnfants as $idCF) {
										$champsActionsParCondition['show'][] = $idCF;
									}
								}
							}
						} elseif ($ac == "hide") {
							//$champsActionsParCondition['hide'][] = $chAc->equivalentSql;
							if (!in_array($chAc->id, $champsActionsParCondition['hide'])) {
								$champsActionsParCondition['hide'][] = $chAc->id;
								//on applique le resultat sur les champs enfants
								if (!empty($champsFormulaire['byParent'][$chAc->id])) {
									$champEnfants = $champsFormulaire['byParent'][$chAc->id];
									foreach ($champEnfants as $idCF) {
										$champsActionsParCondition['hide'][] = $idCF;
									}
								}
							}
						} elseif ($ac == "liste") {
							$champsActionsParCondition['liste'][$chAc->id] = array('valeursSelect' => $acRow['valeursSelect'], 'defaultListeMode' => $acRow['defaultListeMode']);
							//on applique le resultat sur les champs enfants
							if (!empty($champsFormulaire['byParent'][$chAc->id])) {
								$champEnfants = $champsFormulaire['byParent'][$chAc->id];
								foreach ($champEnfants as $idCF) {
									$champsActionsParCondition['liste'][$idCF] = array('valeursSelect' => $acRow['valeursSelect'], 'defaultListeMode' => $acRow['defaultListeMode']);
								}
							}
						} elseif($ac == "required") {
							$champsActionsParCondition['required'][] = $chAc->id;
						}
					}
				}
			}
			syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions Identification Fin");
		}

		// echo "<pre>";
		// var_dump($champsActionsParCondition);
		// echo "</pre>";
		// die();

		## Lecture des types de champs des formulaires
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$typesChampsResult = $typeChampsTable->select();
		$typesChamps = array();
		foreach ($typesChampsResult as $tc) {
			$typesChamps[$tc->id] = $tc;
		}

		## Lecture des résidences et types de logements par résidence
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$residences = $this->getResidencesTable()->fetchAll();
		$residenceOptions = array();
		foreach ($residences as $residence) {
			$typesL = $this->getTypelogementTable()->fetchByResidence($residence->id);
			$allowedResid = false;
			foreach ($typesL as $t) {
				if (in_array($t->idTypeLogement, $typesLogIds)) {
					$allowedResid = true;
				}
			}
			if ($allowedResid) {
				$residenceOptions[$residence->id] = $residence->nom;
			}
		}

		## Tentative de traiter d'abord les actions
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions 1 Deb");
		$forms->buffer();	## Pour pouvoir itérer 2 fois

		//on cherche tout les formulaire pour les actions
		$formsAll = $this->getFormulaireTableModel()->getAllBOForms($idCampagne, $idProfile, -1);

		foreach ($formsAll as $formRow) {
			if ($formRow->afficherEnBO == '-1') {
				continue;
			}
			$champsId = $champsFormulaire['byForm'][$formRow->id];
			if (empty($champsId)) {
				continue;
			}

			foreach ($champsId as $champId) {
				$champ	= $champsFormulaire['byId'][$champId];
				if (in_array($champ->id, $idsChampsActions)) {
					if ($idResaADupliquer > 0) {
						if ($champ->dupliquerValeur != 1 && !empty($locAllInfosObj[$champ->equivalentSql])) {
							//on vide les champs a ne pas copier
							unset($locAllInfosObj[$champ->equivalentSql]);
						}
					}
					if(!array_key_exists($champ->equivalentSql, $locAllInfosObj) && $champ->valeurParDefaut) {
						$locAllInfosObj[$champ->equivalentSql] = $champ->valeurParDefaut;
					}

					$dataActions = $locAllInfosObj;
					$currField = $champ->name;
					$dataActions['currentField'] = $currField;
					$dataActions['idCampagne'] = $idCamp;
					$dataActions['idTypeLocataire'] = $resa ? $resa->idTypeLocataire : null;
					$dataActions['idResa'] = $resa ? $resa->idResa : null;
					$returnActions = $this->loadActions($dataActions, $champsFormulaire);
					syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId currField=$currField nb_returnActions=".count($returnActions['actionResult']));

					// if ($champ->id == "3985") {
					// 	echo "<pre>";
					// 	var_dump($returnActions['actionResult']);
					// 	echo "</pre>";
					// 	die();
					// }

					if (!empty($returnActions['actionResult'])) {
						$acRows = $returnActions['actionResult'];
						foreach ($acRows as $acRow) {
							$ac = $acRow['action'];
							$chAc = $acRow['champ'];
							syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId currField=$currField : action=$ac champ=".$chAc->name." (".$chAc->id.")");
							if ($ac == "show") {
								if (!in_array($chAc->id, $champsActionsParCondition['show'])) {
									$champsActionsParCondition['show'][] = $chAc->id;
									//on applique le resultat sur les champs enfants
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];
										foreach ($champEnfants as $idCF) {
											$exitA = false;
											// on vérifie si le champ n'existe pas déjà dans hide
											foreach ($champsActionsParCondition['hide'] as $keyA => $valueH) {
												if ($valueH == $idCF) {
													$existA = true;
													break;
												}
											}

											if (!$existA) {
												$champsActionsParCondition['show'][] = $idCF;
											}
										}
									}

									// if ($chAc->id == "3191") {
									// 	echo "<pre>";
									// 	var_dump($champsFormulaire['byParent']);
									// 	echo "</pre>";
									// 	die();
									// }
								}
							} elseif ($ac == "hide") {
								if (!in_array($chAc->id, $champsActionsParCondition['hide'])) {
									$champsActionsParCondition['hide'][] = $chAc->id;

									//on applique le resultat sur les champs enfants
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];
										foreach ($champEnfants as $idCF) {
											$exitA = false;
											// on vérifie si le champ n'existe pas déjà dans hide
											foreach ($champsActionsParCondition['show'] as $keyA => $valueH) {
												if ($valueH == $idCF) {
													$existA = true;
													break;
												}
											}

											if (!$existA) {
												$champsActionsParCondition['hide'][] = $idCF;
											}
										}
									}
								}
							} elseif($ac == "required") {
								$champsActionsParCondition['required'][] = $chAc->id;
							}
						}
					}
				}
			}
		}
		//print_r($champsActionsParCondition['required']);exit();
		// echo "<pre>";
		// var_dump($champsActionsParCondition);
		// echo "</pre>";
		// die();

		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions 1 Fin");
		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : champsActionsParCondition=".json_encode($champsActionsParCondition));

		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : idProfile=$idProfile nbForms=".$forms->count()." nbChampsFormulaire=".count($champsFormulaire['byId']));
		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions 2 Deb");

		$champEtatReservation = false;

		foreach ($forms as $formRow) {
			if ($formRow->afficherEnBO == '-1') {
				continue;
			}

			$form = new Form($formRow->name);
			//$champs = $this->getChampsFormulaireTable()->select(array('idFormulaire'=>$formRow->id,'active'=>1));
			$champsId = !empty($champsFormulaire['byForm'][$formRow->id]) ? $champsFormulaire['byForm'][$formRow->id] : array();
			if (empty($champsId) && $formRow->idType == 1) {
				continue;
			}

			## Formulaires de type : Catégorie de documents
			if ($formRow->idType == 12) {
				$formsCatDocs[$formRow->id] = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp, array('idFormulaire' => $formRow->id)), 'UTF-8', 'UTF-8');
			}

			## Formulaires de type :  multisuivis
			if ($formRow->idType == 13) {
				$TSOutput = '';
				$typesSuivisForm = $this->getTypeSuivisFormulaireTable()->getTypeSuivisDeFromulaire($formRow->id);
				foreach ($typesSuivisForm as $TSF) {
					## on vérifie si on a le droit d'affiche ce type suivis dans la campagne

					//$allowdCamp = $this->getTabsDroitParCampagne($idCampagne,'ficheSuivis'.$TSF->idTypeSuivis);
					$TSOutput .= $this->loadSuivisTab($idResa, $TSF->idTypeSuivis, array('idDp' => $idDp, 'idFormulaireCampagne' => $formRow->id));
				}
				$formsSuivis[$formRow->id] = $TSOutput;
			}

			$dateFields = array();
			$allFields = array();
			$cols = array();
			$numRows = array();
			$actionOnCheck = array();
			$conteurTypeLogement = 0;

			syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." nameForm=".$formRow->name." Deb");
			foreach ($champsId as $champId) {
				$champ	= $champsFormulaire['byId'][$champId];
				if($champ->equivalentSql == 'idReservationUsager' || $champ->equivalentSql == 'idUsager') {
					$champ->modifiable = 0;
				}

				//les champs ré afficher
				if ($champ->idParent > 0) {
					$champParent = $champsFormulaire['byId'][$champ->idParent];

					// si on l'a pas trouvé dans la variable champsFormulaire => il se peut que le champ soit désactivé requête de base initialisation ligne 7746
					if (!$champParent) {
						$champParentCheck = $this->getTableObjet('champs_formulaires')
						->select(array('id' => $champ->idParent))->current();
						if ($champParentCheck && $champParentCheck->active == '0') {
							$champParent = $champParentCheck;
						}
					}

					if ($champParent) {
						$champ->parent = $champParent;
						$sessData[$champ->equivalentSql] = $sessData[$champParent->equivalentSql];
						if ($champ->idType == 3) {
							$champ->sourceListe = $champParent->sourceListe;
						}
						$champ->options = $champParent->options;
						$champ->formule = $champParent->formule;
						$champ->idSousType = $champParent->idSousType;
						$champ->showAsSelectItem = $champParent->showAsSelectItem;
						$champ->itemsRequiredToActivateSelect2 = $champParent->itemsRequiredToActivateSelect2;
						$champ->formatFormule = $champParent->formatFormule;
						$champ->idCss	.= " ".$champParent->idCss;
						if (in_array($champ->idParent, $idsChampsActions)) {
							$champ->classCss	.= " avecAction ";
						}
					}
				}

				// Suffixer les labels des champs obligatoires par '*'
				if ($champ->obligatoire) {
					$champ->classCss	.= " champObligatoire ";
				}
				if (in_array($champ->id, $idsChampsActions)) {
					syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." idChamp=".$champ->id." currField=".$champ->name." type=".$champ->idType." avecAction");
					$champ->classCss	.= " avecAction ";
				} else {
					syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." idChamp=".$champ->id." currField=".$champ->name." type=".$champ->idType);
				}
				/*if($champ->equivalentSql =="dateArrivee" || $champ->equivalentSql =="dateDepart"){
					continue;
				}*/
				//$dynamique = $this->getChampdynamiqueTable()->getChampByName($champ->equivalentSql);
				$cols[$champ->column] = $champ->column;
				$type = $typesChamps[$champ->idType];
				$numRows[$champ->row] = $champ->row;
				$readonly = $disabled = false;

				if ($formRow->readonlyBO == 1 || strpos($champ->classCss, 'desactiver') !== false || $champ->modifiable == 0 || $champ->idChampSuivis > 0) {
					$readonly = $disabled = true;
				}

				if ($idResaADupliquer > 0) {
					$readonly = $disabled = false;
				}

				if (/*$_SESSION['USERDROIT']['zfcadmin/liste'] != 'W' || */$_SESSION['USERDROIT']['ficheclient/ficheLocataire'] != 'W') {
					$readonly = $disabled = true;
				}

				$options = array();
				$disabledOptions	= array();
				$isCatalogue = false;
				if (($type->type == "Select" || $type->type == "Multiple-Select")  && $champ->sourceListe) {
					//partie type logement
					if ($champ->sourceListe == "type_logement") {
						$conteurTypeLogement++;
						$emptyOption = "t_Choisissez";
						$nbrTypes = sizeof($typesLog);

						if ($conteurTypeLogement <= $nbrTypes) {
							foreach ($typesLog as $tl) {
								if ($langue == 'en_US') {
									$options[$tl->id] = !empty($tl->nomEn) ? $tl->nomEn : $tl->nom;
								} else {
									$options[$tl->id] = $tl->nom;
								}
								## on cherche la traduction
								$where = array('idLigne'=>$row->id,'codeLangue'=>$langue,'tableReference'=>$champ->sourceListe);
								$ligneTraduit = $this->getTraductionTable()->fetchBy($where)->current();
								if ($ligneTraduit) {
									$options[$row->id] = $ligneTraduit->textTraduit;
								}


								$typesLogement[$formRow->id][$tl->id] = $tl;
							}

							if (count($typesLogement) > 0) {
								$residencesRows = [];
								$typeLogeRows = [];

								// var_dump($idCamp);die();
								// récuéprer toutes les villes => les résidences qui y sont rattachés ainsi que les type de logement
								$tarifsTable = $this->getTableObjet('tarifs')
								->select(array('idCampagne' => $idCamp))->toArray();

								if (count($tarifsTable) > 0) {
									## Extraire de la liste des tarifs une éventuelle limitation des résidences
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$limitResidencesParTarif	= [];
									$avecAllResidences		= false;
									foreach ($tarifsTable as $key => $trT) {
										if ($trT['idResidence']) {
											$limitResidencesParTarif[$trT['idResidence']][]	= $trT['idTypeLogement'];
										} else {
											$avecAllResidences	= true;
										}
									}
									if ($avecAllResidences) {
										$limitResidencesParTarif	= [];
									}
									## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme avecAllResidences=$avecAllResidences limitResidencesParTarif=".json_encode($limitResidencesParTarif));
									foreach ($tarifsTable as $key => $trT) {
										$typeLogementTableArr = $this->getTableObjet('type_logement')
										->select(array('id' => $trT['idTypeLogement']))->current();

										// on filtre par canal
										$typelogement_programme = $this->getTableObjet('typelogement_programme')
										->select(array(
											'idProgramme' => $idProgramme,
											'idCampagne' => $idCamp,
											'idTypeLogement' => $typeLogementTableArr->id,
										))->current();

										## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme tarifTable=".json_encode($trT)." typelogement_programme=".json_encode($typelogement_programme));
										if ($typelogement_programme) {
											$choixTypeLo[] = (array) $typeLogementTableArr;
											$typeLogementTableArr->residence = [];


											// pour chaque type de lgoement on récupère les batiments
											if ($typeLogementTableArr) {
												$typelogement_batimentArr = $this->getTableObjet('typelogement_batiment')
												->select(array('idTypeLogement' => $typeLogementTableArr->id))->toArray();

												// print_r($typelogement_batimentArr);die();
												if (count($typelogement_batimentArr) > 0) {
													foreach ($typelogement_batimentArr as $key => $tlba) {
														$batimentsArr = $this->getTableObjet('batiments')
														->select(array('id' => $tlba['idBatiment']))->toArray();

														if (count($batimentsArr) > 0) {
															foreach ($batimentsArr as $key => $btar) {
																$residencesArr = $this->getTableObjet('residences')
																->select(array('id' => $btar['idResidence']))->toArray();

																if (count($residencesArr) > 0) {
																	foreach ($residencesArr as $key => $rAr) {

																		// $addResidence = true;

																		// if (count($residencesRows) > 0) {
																		// 	foreach ($residencesRows as $key => $rr) {
																		// 		if ($rr['id'] == $rAr['id']) $addResidence = false;
																		// 	}
																		// }

																		// if ($addResidence) {
																		if (!$limitResidencesParTarif || ($limitResidencesParTarif[$rAr['id']] && in_array($typeLogementTableArr->id, $limitResidencesParTarif[$rAr['id']]))) {
																			## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme rArId=$rAr[id] dans limitResidencesParTarif=".json_encode($limitResidencesParTarif));
																			$typeLogementTableArr->residences[] = $rAr;

																			$typeLogeRows[] = $typeLogementTableArr;

																			// $rAr['choixTypeLogement'] = (Array)$typeLogementTableArr;
																			$residencesRows[$rAr['id']]	= $rAr;
																		} else {
																			## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme rArId=$rAr[id] absent de limitResidencesParTarif=".json_encode($limitResidencesParTarif));
																		}
																		// }
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
								## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme typeLogeRows=".json_encode($typeLogeRows));
								## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." idCamp=$idCamp idProg=$idProgramme residencesRows=".json_encode($residencesRows));

								$byGroupVille = $this->group_by("ville", $residencesRows);
								$byGroupNomResidences = $this->group_by("nom", $residencesRows);
								// $byGroupChoixTypeLo = $this->group_by("nom", $choixTypeLo);

								if (count($byGroupVille) > 0) {
									foreach ($byGroupVille as $key => $bgv) {
										$idK = 'residence-';
										if (count($bgv) > 0) {
											foreach ($bgv as $keyB => $v) {
												$idK .= $v['id'] . '-';
											}
										}

										if (strpos($idK, "-") !== false) {
											$idK = substr($idK, 0, -1);
											$villeOptions[$idK] = $key;
										}
									}
								}

								$residenceOptions	= [];
								if (count($residencesRows) > 0) {
									foreach ($residencesRows as $key => $rr) {
										$residenceOptions[$rr['id']] = $rr['nom'];
									}
								}

								if (count($typeLogeRows) > 0) {
									foreach ($typeLogeRows as $key => $ctrtypeloge) {
										$idK = 'residence-';
										if (count($ctrtypeloge->residences) > 0) {
											foreach ($ctrtypeloge->residences as $keyB => $r) {
												$idK .= $r['id'] . '-';
											}
										}

										if (strpos($idK, "-") !== false) {
											$idK = substr($idK, 0, -1);
											$idK .= '-'. $ctrtypeloge->id;
											//$choixTypeLoR[$idK] = $ctrtypeloge->nom;

											$opt = array('label' => $ctrtypeloge->nom, 'value' => $idK,
											'attributes' => array('data-idtl' => $ctrtypeloge->id),
											);
											$choixTypeLoR[$idK] = $opt;
										}
									}
								}

								$form->add(array(
								 'type' => 'Zend\Form\Element\Select',
								 'name' => 'villeOptions',
								 'options' => array(
										 // 'label' => 'Ville *',
										 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
										 'value_options' => $villeOptions,
									 ),
									 'attributes' => array(
										 'class' => 'form-control champObligatoire villeOptions',
										 // 'id' => 'id-villeOptions',
									 ),
								 ));

								asort($residenceOptions);
								## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." residenceOptions=".json_encode($residenceOptions));
								$form->add(array(
								 'type' => 'Zend\Form\Element\Select',
								 'name' => 'residenceOptions',
								 'options' => array(
										 // 'label' => 'Résidence *',
										 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
										 'value_options' => $residenceOptions,
									 ),
									 'attributes' => array(
										 'class' => 'form-control champObligatoire residenceOptions',
										 // 'id' => 'id-residenceOptions',
									 ),
								 ));

								if(!empty($choixTypeLoR))asort($choixTypeLoR);
								## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." choixTypeLoR=".json_encode($choixTypeLoR));
								$form->add(array(
								 'type' => 'Zend\Form\Element\Select',
								 'name' => 'choixTypeLo',
								 'options' => array(
										 // 'label' => 'Choix du type de logement *',
										 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
										 'value_options' => $choixTypeLoR,
									 ),
									 'attributes' => array(
										 'class' => 'form-control champObligatoire choixTypeLo',
										 'data-id' => $champ->id,
										 // 'id' => 'id-choixTypeLo',
										 // 'required' => true, // rendre le champ choix du type de logement en obligatoire
									 ),
								 ));
							}
						} else {
							continue;
						}
						//fin partie type logement
					} elseif (is_numeric($champ->sourceListe)) {
						$valChamp = !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : null;
						$rows = $this->getSelectOptions($champ->sourceListe, array(), array('valeurBdd' => $valChamp));
						$emptyOption = "t_Choisissez";
						foreach ($rows as $row) {
							$options[$row->id] = $row->valeur;
							if ($champ->equivalentSql == 'libre_statut_cao' && $row->valeur == "TRANSFERE") {
								$disabledOptions[]	= $row->id;
							}
							## on cherche la traduction
							$where = array('idLigne'=>$row->id,'codeLangue'=>$langue,'tableReference'=>$champ->sourceListe);
							$ligneTraduit = $this->getTraductionTable()->fetchBy($where)->current();
							if ($ligneTraduit) {
								$options[$row->id] = $ligneTraduit->textTraduit;
							}
						}
					} elseif ($champ->sourceListe == "user") {
						//on recup le critere d affichage dans champs_de_base
						$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql' => 'idUser'))->current();
						$codeType = '';
						if ($champ->options && substr($champ->options, 0, 8) == 'codeType') {
							$codeType = str_replace('codeType_', '', $champ->options);
						} elseif ($cb && $cb->critere) {
							$codeTypeArr = json_decode($cb->critere, true);
							if (!empty($codeTypeArr['codeType'])) {
								$codeType = $codeTypeArr['codeType'];
							}
						}
						if ($codeType) {
							$idResidenceUser = null;
							if ($residenceDeLogement) {
								$idResidenceUser = $residenceDeLogement->idResidence;
							} elseif ($residenceOrientation) {
								$idResidenceUser = $residenceOrientation->id;
							} elseif($residenceDeCampagne) {
								$idResidenceUser = $residenceDeCampagne->id;
							}
							$optionsU = $this->getUserTable()->getUsersListeByCodeType($codeType, $idCampagne, $idResidenceUser);
							$usersDeleted = $this->getUserTable()->getUsersDeletedByCodeType($codeType, $idCampagne, $idResidenceUser);
							$options = array();
							$idUserBdd = !empty($locAllInfosObj[$champ->equivalentSql]) ? $locAllInfosObj[$champ->equivalentSql] : null;
							foreach ($optionsU as $id => $nom) {
								$disabledUser = false;
								if (array_key_exists($id, $usersDeleted)) {
									if ($idUserBdd && $idUserBdd == $id) {
										//$disabledUser = true;
									} else {
										continue;
									}
								}
								$opt = array('label' => $nom, 'value' => $id,
								'attributes' => array('disabled' => $disabledUser),
								);
								$options[] = $opt;
							}
						}
					} elseif ($champ->sourceListe == "logements" && ($residenceDeCampagne || $residenceDeLogement || $residenceOrientation)) {
						//on recup des logements dispo de residence

						$dateArriveeS = (!empty($locAllInfosObj['dateArrivee']) && $tools->isValideDate($locAllInfosObj['dateArrivee'])) ? $locAllInfosObj['dateArrivee'] : "";

						$logeVille = !empty($locAllInfosObj['logeVille']) ? $locAllInfosObj['logeVille'] : "";
						$logeCP = !empty($locAllInfosObj['logeCP']) ? $locAllInfosObj['logeCP'] : "";

						$whereDispo = array('dateDebut' => $dateArriveeS);
						if(array_key_exists('logeVille',$champsFormulaire['byName'])) $whereDispo['logeVille'] = $logeVille;
						if(array_key_exists('logeCP',$champsFormulaire['byName'])) $whereDispo['logeCP'] = $logeCP;
						
						if ($residenceDeLogement) {
							$whereDispo['idResidence'] = array($residenceDeLogement->idResidence);
						} elseif ($residenceOrientation) {
							$whereDispo['idResidence'] = array($residenceOrientation->id);
						} elseif ($residenceDeCampagne) {
							$whereDispo['idResidence'] = array($residenceDeCampagne->id);
						}
						if (($idLogementCur = $locAllInfosObj['idLogement']) > 0) {
							$whereDispo['idLogementCur']	= $idLogementCur;
						}
						$returnLoge = $this->getLogementsDispo($whereDispo);
						$options = !empty($returnLoge['logementsOptions']) ? $returnLoge['logementsOptions'] : array();
					} elseif ($champ->sourceListe == "nationalites") {
						$emptyOption	= "t_Choisissez";
						$options	= array();
						$rows		= $this->getTable('nationalites')->select();
						if (!$rows || !($nbNationalites = $rows->count())) {
							$rows = $this->getTable('pays')->select();
						}
						foreach ($rows as $row) {
							$options[$row->id] = $row->nationalite;
						}
						/*}elseif($champ->sourceListe == "pays"){
							$emptyOption	= "t_Choisissez";
							$options	= array();
							$rows = $this->getTable('pays')->select();
							foreach($rows as $row){
								if($champ->equivalentSql == "idNationalite"){
									$options[$row->id] = $row->nationalite;
								}else{
									$options[$row->id] = $row->pays;
								}
							}
						*/
					} elseif ($champ->sourceListe == "residencesDeCampagne") {
						$emptyOption    = "t_Choisissez";
						$options        = array();
						if ($idCamp) {
							$residencesDeCampagne = $this->getResidencesTable()->getResidencesDeCampagne($idCamp);
							foreach ($residencesDeCampagne as $residence) {
								$options[$residence->id] = $residence->nom;
							}
						}
					} elseif ($champ->equivalentSql == 'residenceLogement' || $champ->equivalentSql == 'residenceOrientation') {
						$dateArriveeS = (!empty($locAllInfosObj['dateArrivee']) && $tools->isValideDate($locAllInfosObj['dateArrivee'])) ? $locAllInfosObj['dateArrivee'] : "";
						$whereDispo = array('dateDebut' => $dateArriveeS);
						if ($residenceDeCampagne) {
							$whereDispo['idResidence'] = array($residenceDeCampagne->id);
						}
						if (($idLogementCur = $locAllInfosObj['idLogement']) > 0) {
							$whereDispo['idLogementCur']	= $idLogementCur;
						}
						$returnLoge = $this->getLogementsDispo($whereDispo);
						$options = !empty($returnLoge['residenceOptions']) ? $returnLoge['residenceOptions'] : array();
					} else {
						// Si sourceListe == menages -> trier les valeurs par ordre alphabétique
						if ($champ->sourceListe == "menages") {
							//$tableMenage = $this->getTableObjet($champ->sourceListe);
							//$selectMenages = $tableMenage->getSql()->select();
							//$selectMenages->order(array('nom ASC'));
							//$rows = $tableMenage->selectWith($selectMenages);
							// Pour permettre d'ajouter un nouveau ménage en haut du select
							//$options[-1] = "t_nouvelle_valeur";
							$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
							$options = $this->getResaTable()->getListeMenages($idCampagne, $gestId, $adapter, $locAllInfosObj['idMenage']);
							$rows = array();

						} else {
							$rows = $this->getTable($champ->sourceListe)->select();
						}
						if ($champ->equivalentSql != 'idPays' && $champ->equivalentSql != 'idNationalite') {
							$emptyOption = "t_Choisissez";
						}
						foreach ($rows as $row) {
							if ($champ->equivalentSql == 'idPays') {
								$options[$row->id] = $row->pays;
							} elseif ($champ->equivalentSql == 'idNationalite') {
								$options[$row->id] = $row->nationalite;
							} elseif ($champ->sourceListe == 'pays') {
								$options[$row->id] = $row->pays;
							} else {
								$options[$row->id] = $row->nom;
							}

							## on cherche la traduction
							//$where = array('idLigne'=>$row->id,'codeLangue'=>$langue,'tableReference'=>$champ->sourceListe);
							//if ($champ->sourceListe=='pays') {
							//$where['champName'] = $champ->equivalentSql;
							//}
							//$ligneTraduit = $this->getTraductionTable()->fetchBy($where)->current();
							//if ($ligneTraduit) {
							//$options[$row->id] = $ligneTraduit->textTraduit;
							//}
						}

						//tri
						if ($idDp > 0) {
							$options = $tools->trierTableau($options);
						}
					}
				} elseif ($residenceDeCampagne || $residenceDeLogement || $residenceOrientation) {
					$idResidenceLoge  = 0;
					if ($residenceDeCampagne) {
						$idResidenceLoge = $residenceDeCampagne->id;
					} elseif ($residenceDeLogement) {
						$idResidenceLoge = $residenceDeLogement->idResidence;
					} elseif ($residenceOrientation && $residenceOrientation > 0) {
						$idResidenceLoge = $residenceOrientation->id;
					}

					$dateArriveeS = (!empty($locAllInfosObj['dateArrivee']) && $tools->isValideDate($locAllInfosObj['dateArrivee'])) ? $locAllInfosObj['dateArrivee'] : "";


					if ($champ->equivalentSql == 'logeVille') {
						$whereDispo = array('idResidence' => array($idResidenceLoge), 'dateDebut' => $dateArriveeS);

						if (!empty($locAllInfosObj['logeVille'])) {
							//$whereDispo['logeVille'] = $locAllInfosObj['logeVille'];//on l'enleve pour afficher les autres villes
						}
						if (!empty($locAllInfosObj['logeCP'])) {
							//$whereDispo['logeCP'] = $locAllInfosObj['logeCP'];//on l'enleve pour afficher les autres CP
						}

						if (($idLogementCur = $locAllInfosObj['idLogement']) > 0) {
							$whereDispo['idLogementCur']	= $idLogementCur;
						}
						$returnLoge = $this->getLogementsDispo($whereDispo);
						$options = !empty($returnLoge['villesOptions']) ? $returnLoge['villesOptions'] : array();
						//on y ajoute la ville du logement en cours
						if (!empty($sessData['logeVille']) && $sessData['logeVille'] != '') {
							$options[$sessData['logeVille']] = $sessData['logeVille'];
						}
					} elseif ($champ->equivalentSql == 'logeCP') {
						$whereDispo = array('idResidence' => array($idResidenceLoge), 'dateDebut' => $dateArriveeS);

						if (!empty($locAllInfosObj['logeVille'])) {
							$whereDispo['logeVille'] = $locAllInfosObj['logeVille'];
						}
						if (!empty($locAllInfosObj['logeCP'])) {
							$whereDispo['logeCP'] = $locAllInfosObj['logeCP'];
						}

						if (($idLogementCur = $locAllInfosObj['idLogement']) > 0) {
							$whereDispo['idLogementCur']	= $idLogementCur;
						}

						$returnLoge = $this->getLogementsDispo($whereDispo);

						$options = !empty($returnLoge['CPOptions']) ? $returnLoge['CPOptions'] : array();
						//on y ajoute le CP du logement en cours
						if (!empty($sessData['logeCP']) && $sessData['logeCP'] != '') {
							$options[$sessData['logeCP']] = $sessData['logeCP'];
						}
					}
				}
				if (($type->type == "Select" || $type->type == "Multiple-Select") && !$champ->sourceListe && strpos($champ->equivalentSql, 'catalogues_') !== false) {
					//prise en comtpe champs catalogues
					$isCatalogue = true;
					$newOption = false;
					$idCatalogue = null;
					$idTypeCatalogue = str_replace('catalogues_', '', $champ->equivalentSql);
					if ($_SESSION['USERDROIT']['liste-btn-creer-catalogue-fiche-usager'] == 'W' || $_SESSION['USERDROIT']['liste-btn-creer-catalogue-fiche-usager'] == 'R') {
						//$options[-1] = 'Nouveau';
						$newOption = true;
					}
					if ($idResa > 0) {
						$idCatalogue = $this->getCatalogueTable()->getCatalogueDeResaByTypeCatalogue($idResa, $idTypeCatalogue);
						$sessData[$champ->equivalentSql] = $locAllInfosObj[$champ->equivalentSql] = $idCatalogue;
					} elseif ($idDp > 0) {
						$idCatalogue = $this->getCatalogueTable()->getCatalogueDeDpByTypeCatalogue($idDp, $idTypeCatalogue);
						$sessData[$champ->equivalentSql] = $locAllInfosObj[$champ->equivalentSql] = $idCatalogue;
					}
					$options = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue, array('newOption' => $newOption, 'idCatalogue' => $idCatalogue, 'gestId' => $gestId));
				}

				//les types doc
				if ($type->type == "File") {
					$docsFields[] = $champ;
				}

				## Résidence logement
				if ($champ->equivalentSql == "residenceLogement" || $champ->equivalentSql == "residenceOrientation") {
					if ($residenceDeLogement) {
						//foreach($options as $c=>$v){
						//if($c != $residenceDeLogement->idResidence) unset($options[$c]);
						//}
						$sessData[$champ->equivalentSql] = $residenceDeLogement->idResidence;
						$locAllInfosObj[$champ->equivalentSql] = $residenceDeLogement->idResidence;
					}
				}

				//champs date
				if ($type->nom == "Date") {
					$dateFields[] = $champ;
					//plages de dates
					$plage = $this->getTable('champs_dateinterval')->select(array('idChamp' => $champ->id))->current();
					if ($plage) {
						$plageMin = $plageMax = "";
						$uniteMin = $uniteMax = "d";
						if ($plage->dateMin == 'limited') {
							$plageMin = $plage->nombreJoursMin;
							if ($plage->uniteMin == "year") {
								$uniteMin = "y";
							} elseif ($plage->uniteMin == "month") {
								$uniteMin = "m";
							} elseif ($plage->uniteMin == "week") {
								$uniteMin = "w";
							} else {
								$uniteMin = "d";
							}
						}
						if ($plage->dateMax == 'dateNow' || $plage->dateMax == 'limited') {
							//dateNow : date du jour +- X unite
							//$plageMax = '-1';
							$plageMax = $plage->nombreJoursMax;
							if ($plage->uniteMax == "year") {
								$uniteMax = "y";
							} elseif ($plage->uniteMax == "month") {
								$uniteMax = "m";
							} elseif ($plage->uniteMax == "week") {
								$uniteMax = "w";
							} else {
								$uniteMax = "d";
							}
						}

						//cas date fixe avec annee dynamique
						if ($plage->dateMinFixe && $plage->uniteMin == 'year') {
							//on recupère l'année en cours, puis on y rajoute ou on diminue le nombre configuré
							$thisYear = date('Y');
							//on recupère le jour et mois de $plage->dateMinFixe
							$mj = date('m-d', strtotime($plage->dateMinFixe));
							$plage->dateMinFixe = $thisYear.'-'.$mj;
							if ($plage->nombreJoursMin > 0) {
								$plage->dateMinFixe = date('Y-m-d', strtotime($plage->dateMinFixe." + ".$plage->nombreJoursMin." year"));
							} elseif ($plage->nombreJoursMin < 0) {
								$plage->nombreJoursMin = abs($plage->nombreJoursMin);//on converti en positive
								$plage->dateMinFixe = date('Y-m-d', strtotime($plage->dateMinFixe." - ".$plage->nombreJoursMin." year"));
							}
						}

						if ($plage->dateMaxFixe && $plage->uniteMax == 'year') {
							//on recupère l'année en cours, puis on y rajoute ou on diminue le nombre configuré
							$thisYear = date('Y');
							//on recupère le jour et mois de $plage->dateMaxFixe
							$mj = date('m-d', strtotime($plage->dateMaxFixe));
							$plage->dateMaxFixe = $thisYear.'-'.$mj;
							if ($plage->nombreJoursMax > 0) {
								$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMaxFixe." + ".$plage->nombreJoursMax." year"));
							} elseif ($plage->nombreJoursMax < 0) {
								$plage->nombreJoursMax = abs($plage->nombreJoursMax);//on converti en positive
								$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMaxFixe." - ".$plage->nombreJoursMax." year"));
							}

							//test de control de plage
							if ($plage->dateMinFixe && strtotime($plage->dateMinFixe) > strtotime($plage->dateMaxFixe)) {
								//on les converti
								$tmp = $plage->dateMinFixe;
								$plage->dateMinFixe = $plage->dateMaxFixe;
								$plage->dateMaxFixe = $tmp;
							}
						} elseif ($plage->dateMinFixe && $plage->uniteMin == 'year' && $plageMax != 0 && $plage->dateMax != 'dateNow') {
							if ($plageMax > 0) {
								$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." + ".$plageMax." ".$plage->uniteMax));
							} else {
								$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." - ".abs($plageMax)." ".$plage->uniteMax));
							}
						}
						//date min +- X unite
						if (($plage->dateMax == 'limited' || $plage->dateMax == 'dateNow') && !$plage->dateMaxFixe) {
							//limited : date min + X unite
							$uMin = $plage->uniteMin ? $plage->uniteMin : "day";
							$uMax = $plage->uniteMax ? $plage->uniteMax : "day";
							$now = date('Y-m-d');
							if ($plage->dateMax == 'dateNow') {
								$opMax = $plage->nombreJoursMax > 0 ? '+' : '';
								$plage->dateMaxFixe = date('Y-m-d', strtotime($now." $opMax ".$plage->nombreJoursMax." ".$uMax));
							} else {
								if ($plage->dateMinFixe) {
									$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." $opMax ".$plage->nombreJoursMax." ".$uMax));
								} else {
									$opMin = $plage->nombreJoursMin > 0 ? '+' : '';

									$dateMin = date('Y-m-d', strtotime($now." $opMin ".$plage->nombreJoursMin." ".$uMin));
									$plage->dateMaxFixe = date('Y-m-d', strtotime($dateMin." $opMax ".$plage->nombreJoursMax." ".$uMax));
								}
							}
						}

						$datesPlage[$champ->id] = array('plageMin' => $plageMin,
														'plageMax' => $plageMax,
														'uniteMin' => $uniteMin,
														'uniteMax' => $uniteMax,
														'dateMin' => $plage->dateMinFixe,
														'dateMax' => $plage->dateMaxFixe,
														);
					}

					## arrivee + depart, intervals selon le canal
				}

				//champ Radio
				if ($type->type == "Radio") {
					$rows = explode(";", $champ->options);
					//on supprime les element vide
					$options = array_filter($rows);
				}

				//champ Set
				if ($type->type == "Set") {
					syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idChamp=".$champ->id." nomChamp=".$champ->name." idType=".$champ->idType." setOptions");
					$rows = explode(";", $champ->options);
					//on supprime les element vide
					$options = array_filter($rows);
				}

				//action oncheck
				if ($type->type == "Checkbox" || $type->type == "Radio" || $type->type == "Set") {
					$actions = $this->getActionsjsTable()->select(array('idChamp' => $champ->id));
					foreach ($actions as $action) {
						$champAttache = $this->getChampsFormTable()->select(array('id' => $action->idChampAttache))->current();
						$actionOnCheck[] = array('champBase' => $champ, 'action' => $action, 'champAttache' => $champAttache);
					}
				}

				if (!in_array($champ->id, $idsChampsActions)) {
					if ($type->type == "Checkbox" || $type->type == "Radio" || $type->type == "Set") {
						$actions = $this->getActionsjsTable()->select(array('idChamp' => $champ->id));
						$valeurCheck = !empty($locAllInfosObj[$champ->equivalentSql]) ? $locAllInfosObj[$champ->equivalentSql] : "";
						foreach ($actions as $action) {
							$champAttache = $this->getChampsFormTable()->select(array('id' => $action->idChampAttache))->current();
							$actionOnCheck[] = array('champBase' => $champ, 'action' => $action, 'champAttache' => $champAttache);

							if ($valeurCheck) {
								$champsAttacheeChecked[] = $champAttache->equivalentSql;
							}
						}
					}
				}

				if (in_array($champ->equivalentSql, $champsAttacheeChecked)) {
					$champ->classCss = str_replace('hide', '', $champ->classCss);
				}
				//champs à cacher, selon les valeur du formulaire de la premiere page
				if (in_array($champ->equivalentSql, $champsAttacheToHide)) {
					$champ->classCss .= ' hide';
				}

				if ($controleTypeLocataire && $champ->equivalentSql == "dateArrivee") {
					//on ajoute dateArrivee au champ attache
					$idsChampsActions[] = $champ->id;
				}

				if (in_array($champ->id, $idsChampsActions)) {
					$dataActions = $locAllInfosObj;
					$dataActions['idCampagne'] = $idCamp;
					$currField = $champ->equivalentSql;
					//on verifie si type logement
					if ($champ->equivalentSql == "idTypeLogement") {
						for ($t = 1;$t <= $maxChoix;$t++) {
							if (!empty($locAllInfosObj['idTypeLogementAttribue'])) {
								$currField = 'idTypeLogement'.$t;
							}
						}
					}
					$dataActions['currentField'] = $currField;
					$dataActions['idTypeLocataire'] = $resa ? $resa->idTypeLocataire : null;
					$dataActions['idResa'] = $resa ? $resa->idResa : null;
					$returnActions = $this->loadActions($dataActions, $champsFormulaire);
					//if($champ->id == 2352){
					//print_r($returnActions);
					//}
					syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." idChamp=$champId currField=$currField nb_returnActions=".count($returnActions['actionResult']));

					if ($dataActions['currentField'] == "dateArrivee") {
						//on fait appel au action type locataire
						$currField = "idTypeLocataire";
						$dataActions['currentField'] = $currField;
						$ret = $this->loadActions($dataActions, $champsFormulaire);
						syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." idChamp=$champId currField=$currField nb_ret=".count($ret['actionResult']));

						if (!empty($ret['actionResult'])) {
							if (!empty($returnActions['actionResult'])) {
								$returnActions['actionResult'] = array_merge($returnActions['actionResult'], $ret['actionResult']);
							} else {
								$returnActions['actionResult'] = $ret['actionResult'];
							}
						}
					}


					if (!empty($returnActions['actionResult'])) {
						$acRows = $returnActions['actionResult'];

						foreach ($acRows as $acRow) {
							$ac = $acRow['action'];
							$chAc = $acRow['champ'];
							syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." idChamp=$champId currField=$currField : action=$ac champ=".$chAc->name." (".$chAc->id.")");
							if ($ac == "show") {
								if (!in_array($chAc->id, $champsActionsParCondition['show'])) {
									$champsActionsParCondition['show'][] = $chAc->id;
									//on applique le resultat sur les champs enfants
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];
										foreach ($champEnfants as $idCF) {
											$champsActionsParCondition['show'][] = $idCF;
										}
									}
								}
								//$dejaAfficher[] = $chAc->equivalentSql;
							} elseif ($ac == "hide") {
								if (!in_array($chAc->id, $champsActionsParCondition['hide'])) {
									$champsActionsParCondition['hide'][] = $chAc->id;

									//on applique le resultat sur les champs enfants
									//print_r($champEnfants);exit();
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];

										foreach ($champEnfants as $idCF) {
											$champsActionsParCondition['hide'][] = $idCF;
										}
									}
								}
							} elseif ($ac == "liste") {
								$champsActionsParCondition['liste'][$chAc->id] = array('valeursSelect' => $acRow['valeursSelect'], 'defaultListeMode' => $acRow['defaultListeMode']);
								//on applique le resultat sur les champs enfants
								if (!empty($champsFormulaire['byParent'][$chAc->id])) {
									$champEnfants = $champsFormulaire['byParent'][$chAc->id];
									foreach ($champEnfants as $idCF) {
										$champsActionsParCondition['liste'][$idCF] = array('valeursSelect' => $acRow['valeursSelect'], 'defaultListeMode' => $acRow['defaultListeMode']);
									}
								}
							} elseif ($ac == "required") {
								$champsActionsParCondition['required'][] = $chAc->id;
							}
						}
					}
				}


				if (!empty($champsActionsParCondition['hide']) && in_array($champ->id, $champsActionsParCondition['hide'])) {
					$champ->classCss = str_replace('hide', '', $champ->classCss);
					$champ->classCss .= ' hide';
				}
				if (!empty($champsActionsParCondition['show']) && in_array($champ->id, $champsActionsParCondition['show'])) {
					$champ->classCss = str_replace('hide', '', $champ->classCss);
				}

				$lmsgid = 'l_'.$champ->name.'_'.$champ->id;
				$imsgid = 'i_'.$champ->name.'_'.$champ->id;

				if ($type->type != "HTML") {

					## valeur par défaut du champ
					if ((empty($sessData[$champ->equivalentSql]) || !$sessData[$champ->equivalentSql]) && $champ->valeurParDefaut) {
						##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idR idLocataire=".$loc->id." idForm=".$formRow->id." champ: name=".$champ->name." type=".$champ->idType.'-'.$type->type.' modifiable='.$champ->modifiable.' equivalentSql='.$champ->equivalentSql.' sessData='.$sessData[$champ->equivalentSql]." set valeurParDefaut=".$champ->valeurParDefaut);
						$sessData[$champ->equivalentSql] = $champ->valeurParDefaut;
					}

					if (($type->type == "Select" || $type->type == "Multiple-Select") && $champ->sourceListe == "type_logement") {
						$idsTL = array();
						foreach ($options as $id => $nom) {
							$idsTL[] = $id;
						}

						for ($i = 1; $i <= $maxChoix; $i++) {
							$champTL = clone $champ;
							$champTL->equivalentSql = $champ->equivalentSql.$i;
							$champTL->idCss = $champ->idCss.$i;
							//$champTL->row = $champ->row + $i-1;

							if ($minChoix >= $i) {
								$champTL->obligatoire = '1';
							} else {
								$champTL->obligatoire = '0';
							}

							$choixRow = $this->getChoixTable()
									->fetchBy(array('idReservation' => $idResa,
													//'idTypeLogement'=>$idTypeLogement,
													'numeroChoix' => $i,
													))
									->current();


							$valeurChamp = $choixRow ? $choixRow->idTypeLogement : "";
							$champTL->classCss = str_replace('typelogement', '', $champTL->classCss);

							if ($modeChoix != 'residenceSeulement') {
								$form->add(array(
									 'name' => $champTL->equivalentSql,
									 'type' => $type->type,
									  'options' => array(
										 'label' => html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8").($maxChoix > 1 ? " ".$i : ''),
										 'label_attributes' => array('class' => 'editable', 'data-msgid' => $lmsgid, 'data-changed' => "0"),
											 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
											 'value_options' => $options,
										),
									 'attributes' => array(
									 'class' => 'form-control typelogement '.$champTL->classCss,
									 'id' => $champTL->idCss,
									 'title' => $champTL->libelle,
									 'data-position' => $i,
											 'value' => $valeurChamp,
											 'disabled' => $disabled,
											 'data-id' => $champTL->id,
										),
								));
							} else {
								## En mode résidence seulement, garder le typeLogement en Hidden dans le formulaire en choisissant le premier
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								reset($options);
								$form->add(array(
									'name' => $champTL->equivalentSql,
									'type' => 'Hidden',
									'attributes' => array(
										'value' => key($options),
									),
								));
							}
							//$numRows[$champTL->row + $maxChoix] = $champTL->row + $maxChoix;
							$allFields[] = $champTL;


							//valeur stocker dans  la sessions
							$selectedResidence = $selectedBatiment = "";
							if ($choixRow) {
								$selectedResidence = $choixRow->idResidence ? $choixRow->idResidence : "";
								$selectedBatiment = $choixRow->idBatiment ? $choixRow->idBatiment : "";
							}

							## le cas ou on doit commencer par choisir le type logement:
							## on devrait pour chaque type, choisir la residence et le batiment

							if ($ordreChoix == "typelogement" && ($modeChoix == 'residence' || $modeChoix == 'batiment')) {
								$residenceOptions = $valeurChamp ? $this->loadResidencesDeType($valeurChamp) : array();


								asort($residenceOptions);
								## syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locId=".$loc->id." residenceOptions=".json_encode($residenceOptions));
								$form->add(array(
									 'name' => 'residence'.$i,
									 'type' => 'Select',
									  'options' => array(
									'label' => html_entity_decode($translator->translate('l_residence').($maxChoix > 1 ? " $i" : ''), ENT_NOQUOTES, "UTF-8"),
										  'label_attributes' => array('class' => 'editable', 'data-msgid' => 'l_residence', 'data-changed' => "0"),
										 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
										 'value_options' => $residenceOptions,
									),
									 'attributes' => array(
										 'class' => 'form-control choix-residence2 list-residences',
										 'id' => 'id-residence'.$i,
										  'title' => 'Residence',
										  'data-position' => $i,
										  'value' => $selectedResidence,
										   'disabled' => $disabled,
										   'data-id' => $champTL->id,
									),
									));

								if ($modeChoix == 'batiment') {
									$batimentOptions = array();
									if ($valeurChamp) {
										$retour = $this->loadBatimentDeResidence($selectedResidence, array($valeurChamp));
										$batimentOptions = $retour['listOptions'];
									}

									$form->add(array(
										 'name' => 'batiment'.$i,
										 'type' => 'Select',
										  'options' => array(
											  'label' => html_entity_decode($translator->translate('l_batiment'), ENT_NOQUOTES, "UTF-8"),
											  'label_attributes' => array('class' => 'editable', 'data-msgid' => 'l_batiment', 'data-changed' => "0"),
											 'empty_option' => html_entity_decode($translator->translate('t_choisissez_residence'), ENT_NOQUOTES, "UTF-8"),
											 'value_options' => $batimentOptions,
										),
										 'attributes' => array(
											 'class' => 'form-control choix-residence2 list-batiments',
											 'id' => 'id-batiment'.$i,
											  'title' => 'Batiment',
											  'value' => $selectedBatiment,
											   'disabled' => $disabled,
										),
										));
								}
							}
						}//end for maxChoix

						if ($ordreChoix == "residence" && ($modeChoix == 'residence' || $modeChoix == 'residenceSeulement' || $modeChoix == 'batiment')) {
							for ($i = 1; $i <= $maxChoix; $i++) {
								$choixRow = $this->getChoixTable()
									->fetchBy(array('idReservation' => $idResa,
													//'idTypeLogement'=>$idTypeLogement,
													'numeroChoix' => $i,
													))
									->current();

								//valeur stocker dans  la sessions
								$selectedResidence = $selectedBatiment = "";
								if ($choixRow) {
									$selectedResidence = $choixRow->idResidence ? $choixRow->idResidence : "";
									$selectedBatiment = $choixRow->idBatiment ? $choixRow->idBatiment : "";
								}

								$valeurChamp = $choixRow ? $choixRow->idTypeLogement : "";

								if ($valeurChamp) {
									$typeOptions = $this->loadTypeLogementResidence($selectedResidence, $idsTL);
									$form->get($champ->equivalentSql.$i)->setAttribute('options', $typeOptions);
									$form->get($champ->equivalentSql.$i)->setValue($valeurChamp);
								}

								## Lecture de la liste des résidences de la campagne
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$residencesDeCampagne	= $this->getResidencesTable()->getResidencesDeCampagne($idCamp);
								$residenceOptions	= array();
								foreach ($residencesDeCampagne as $residence) {
									if (!$limitResidencesParTarif || count($limitResidencesParTarif[$residence->id]) > 0) {
										$residenceOptions[$residence->id] = $residence->nom;
									}
								}
								asort($residenceOptions);
								## syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idCamp=$idCamp formId=".$formRow->id." formAdd residence$i residenceOptions=".json_encode($residenceOptions));
								$form->add(array(
								 'name' => 'residence'.$i,
								 'type' => 'Select',
								  'options' => array(
								'label' => html_entity_decode($translator->translate('l_residence').($maxChoix > 1 ? " $i" : ''), ENT_NOQUOTES, "UTF-8"),
									 'label_attributes' => array('class' => 'editable', 'data-msgid' => 'l_residence', 'data-changed' => "0"),
									 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
									 'value_options' => $residenceOptions,
								),
								 'attributes' => array(
									 'class' => 'form-control choix-residence choix-de-residence ',
									 'id' => 'id-residence'.$i,
									  'title' => html_entity_decode($translator->translate('l_residence'), ENT_NOQUOTES, "UTF-8"),
									  'value' => $selectedResidence,
									  'data-position' => $i,
									   'disabled' => $disabled,
									   'data-id' => $champTL->id,
								),
								));

								if ($modeChoix == 'batiment') {
									$batimentOptions = array();
									if ($valeurChamp) {
										$retour = $this->loadBatimentDeResidence($selectedResidence, $typesLogIds);
										$batimentOptions = $retour['listOptions'];


										$typeOptions = $this->loadTypeLogementBatiment($selectedBatiment, $idsTL);
										$form->get($champ->equivalentSql.$i)->setAttribute('options', $typeOptions);
										$form->get($champ->equivalentSql.$i)->setValue($valeurChamp);
									}

									$form->add(array(
									 'name' => 'batiment'.$i,
									 'type' => 'Select',
									  'options' => array(
										  'label' => html_entity_decode($translator->translate('l_batiment'), ENT_NOQUOTES, "UTF-8"),
										  'label_attributes' => array('class' => 'editable', 'data-msgid' => 'l_batiment', 'data-changed' => "0"),
										 'empty_option' => html_entity_decode($translator->translate('t_choisissez_residence'), ENT_NOQUOTES, "UTF-8"),
										 'value_options' => $batimentOptions,
										  'disabled' => $disabled,
									),
									 'attributes' => array(
										 'class' => 'form-control choix-residence choix-de-batiment',
										 'id' => 'id-batiment'.$i,
										  'title' => 'Batiment',
										  'value' => $selectedBatiment,
										  'data-position' => $i,
									),
									));
								}
							}
						}//end if residence-batiment
					} elseif ($champ->equivalentSql != "") {

						//$champ->classCss = str_replace('hide',' ',$champ->classCss);//on affiche tout les champs caché
						//$champ->classCss = "";
						/*if (strpos($champ->classCss, 'hide') !== false) {
							$champ->classCss = str_replace('hide',' ',$champ->classCss);//on affiche tout les champs caché
							$champ->obligatoire = 0;
						}*/

						if ($champ->equivalentSql == 'nomResidence' && $residenceDeCampagne) {
							$sessData[$champ->equivalentSql] = $residenceDeCampagne->nom;
							$readOnly = true;
						}

						if ($idResaADupliquer > 0) {
							if ($champ->dupliquerValeur != 1 && !empty($sessData[$champ->equivalentSql])) {
								//on vide les champs a ne pas copier
								unset($sessData[$champ->equivalentSql]);
								unset($locAllInfosObj[$champ->equivalentSql]);
							}
							## On garde la valeur par défaut, en cas de duplication
							if(!array_key_exists($champ->equivalentSql, $locAllInfosObj) && $champ->valeurParDefaut) {
								$locAllInfosObj[$champ->equivalentSql] = $champ->valeurParDefaut;
							}
						}

						## champ formule
						if ($champ->idType == 13) {
							$readOnly = true;
						}


						## Traitement champs de l'onglet séjour / réservation
						## on regarde si on a un modèle de facture pour le dossier sinon on met le cham en readOnly
						if($champ->equivalentSql == 'pasDeFacture' && $resa && $resa->numDossier) {
							$retPDF = $this->lirePasDeFacture($resa->id);
							if(!is_array($retPDF) || (is_array($retPDF) && empty($retPDF))) {
								$disabled = true;
								$readOnly = false;
								$lmsgid = "Pas de modéle de facture pour ce dossier";
							}
						}
						if(in_array($champ->equivalentSql, array('etat', 'dateDemandeReservation', 'typre'))) {
							$disabled = true;
							if($champ->equivalentSql == 'typre') {
								$options = array('R' => 'Résident', 'P' => 'Passager');
							}
							$readOnly = false;
						}
						##-----------

						$classFormMonetaire = $champ->idType . ' aligner_left';
						if ($champ->afficherUnite == "0" && $champ->idType == 13) {
							$classFormMonetaire = "";
						}

						$champ->classCss .= " type_".$classFormMonetaire." ";

						if ($champ->aligner != "") {
							$champ->classCss .=  $champ->aligner." ";
						}
						if ($champ->afficherInfos == 1) {
							$champ->classCss .=  "showinfos ";
						}
						if ($champ->idType == 6) {
							$champ->classCss .=  "showMailTo ";
						}

						if ($champ->idChampSuivis > 0) {
							$libelle = $champ->libelle;
						} else {
							$libelle = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");
						}

						if ($type->type == "Radio") {
							$attrChamp = array(
								'class' => ''.$champ->classCss.' '.$champ->idCss,
								'id' => $champ->idCss,
								'title' => html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8"),
								'value' => !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : "",
								'rows' => $type->type == 'Textarea' ? $champ->tailleRow : '',
								'readonly' => $readonly,
								'disabled' => $disabled,
								'data-parent' => $champ->idParent > 0 ? $champ->idParent : '',
								'data-parentname' => $champ->parent ? $champ->parent->equivalentSql : '',
								'data-nature' => $champ->nature,
								'data-id' => $champ->id,
								'data-idtype' => $champ->idType,
								'data-champcommun' => $champ->idChampCommun > 0 ? $champ->idChampCommun : '',
								'data-preval' => !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : "",
							);

							// rendre les champ dupliquer en read only pour éviter tout changement parce que dans valeur_dynamiques on enregistre que l'oririginal
							//if ($champ->idParent>0) $attrChamp['readonly'] = 'readonly';

							$form->add(array(
								'name' => $champ->equivalentSql,
								'type' => $type->type,
								'options' => array(
									'label' => $libelle,
									 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
									 'value_options' => $options,
									 'label_attributes' => array('class' => 'radioLabel margin-right-10 ',
																'data-msgid' => $lmsgid,
																'data-title' => html_entity_decode($translator->translate($imsgid), ENT_NOQUOTES, "UTF-8"),
																),
								),
								'attributes' => $attrChamp,
							));

							$champ->extraClass = ''.$champ->classCss.' '.$champ->idCss;
						} elseif ($type->type == "Set") {
							$formChampName		= $champ->equivalentSql.'_'.$champ->sourceListe;
							$formChampSessData	= $sessData[$champ->equivalentSql];
							$formChampValue		= !empty($formChampSessData) ? (strpos($formChampSessData, $champ->sourceListe) === false ? 0 : 1) : 0;
							syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idChamp=".$champ->id." nomChamp=".$champ->name." formChampName=$formChampName sessData=$formChampSessData formChampValue=$formChampValue");
							$attrChamp = array(
								'class' => ''.$champ->classCss.' '.$champ->idCss,
								'id' => $champ->idCss,
								'title' => html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8"),
								'value' => $formChampValue,
								'rows' => $type->type == 'Textarea' ? $champ->tailleRow : '',
								'readonly' => $readonly,
								'disabled' => $disabled,
								'data-parent' => $champ->idParent > 0 ? $champ->idParent : '',
								'data-parentname' => $champ->parent ? $champ->parent->equivalentSql : '',
								'data-nature' => $champ->nature,
								'data-id' => $champ->id,
								'data-idtype' => $champ->idType,
								'data-champcommun' => $champ->idChampCommun > 0 ? $champ->idChampCommun : '',
								'data-preval' => $formChampValue,
							);

							// rendre les champ dupliquer en read only pour éviter tout changement parce que dans valeur_dynamiques on enregistre que l'oririginal
							//if ($champ->idParent>0) $attrChamp['readonly'] = 'readonly';

							$form->add(array(
								'name' => $formChampName,
								'type' => 'Radio',
								'options' => array(
									'label' => $libelle,
									 'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
									 'value_options' => $options,
									 'label_attributes' => array('class' => 'radioLabel margin-right-10 ',
																'data-msgid' => $lmsgid,
																'data-title' => html_entity_decode($translator->translate($imsgid), ENT_NOQUOTES, "UTF-8"),
																),
								),
								'attributes' => $attrChamp,
							));

							$champ->extraClass = ''.$champ->classCss.' '.$champ->idCss;
						} else {
							//$readOnly = false;
							if (!empty($params) && !empty($params['dateArrivee']) && !empty($params['dateDepart'])) {
								if ($champ->equivalentSql == "dateArrivee" || $champ->equivalentSql == "dateDepart") {
									//$readOnly = true;
								}
							}
							//on enleve
							$classBT = "form-control";
							if ($type->type == "Checkbox") {
								$classBT = "";
							}


							if ($champ->equivalentSql == "idLogement" && ($_SESSION['USERDROIT']['liste-input-btn-change-loge'] == 'W' || $_SESSION['USERDROIT']['liste-input-btn-change-loge'] == 'R')) {
								$champ->classCss .= ' width-80 ';
							}

							if($champ->equivalentSql == "etat" && $champ->sourceListe == 'etat_reservation') {
								$champEtatReservation = true;
							}

							if ($champ->equivalentSql == "idLogement" && $resa && $resa->idLogement > 0 && (!$modeCampagne || $modeCampagne->chgLogSansNouvelleResa != 1)) {
								$readOnly = true;
								$disabled = true;
							}

							//champs fiancnier en readonly
							if (is_array($champsFinancier) && $champ->nature == 'standard' && array_key_exists($champ->equivalentSql, $champsFinancier)) {
								$readOnly = true;
								$disabled = true;
							}

							if (!in_array($champ->idType, array(3, 8, 18)) && $readOnly == true) {
								$disabled = false;//pb de perte des infos des champs disabled à la validation
							}


							$classPlg = $champ->idType == 14 ? 'plg-intlTelInput' : '';

							## exclure les sites avec csi_conso==1, si il si champ residence orientation
							if ($champ->equivalentSql == "residenceOrientation" || $champ->equivalentSql == "residenceLogement") {
								$residGest = $this->getResidencesTable()->fetchByGest($gestId);
								$options = array();
								foreach ($residGest as $row) {
									$options[$row->id] = $row->nom;
								}

								$idsToExclure = $this->getGlobalHelper()->getIdsResidencesOrienAExclure();
								if (!empty($idsToExclure)) {
									foreach ($idsToExclure as $idR) {
										if (array_key_exists($idR, $options)) {
											unset($options[$idR]);
										}
									}
								}
							}



							## pour les champs catalogues
							if ($isCatalogue) {
								$champ->classCss .=  "champCatalogue ";
							}
							if ($champ->styleCss) {
								$classPlg .= ' borderStyle';
							}
							if($champ->modifierListe == 1 && ($champ->idType == 3 || $champ->idType == 18)){
								$champ->classCss .=  "modifierListe ";
							}
							$dateFormat = ($langue == 'en_US')? "yyyy-mm-dd":"jj-mm-aaaa";
							$modeleDoc = null;
							if($champ->idType == 22 && $champ->valeurParDefaut){
								$modeleDoc = $this->getTableObjet('type_modeles_docs')->select(array('id' => $champ->valeurParDefaut))->current();
							}
							try {
								$attributes	= array(
									 'class' => $classBT.' '.$champ->classCss.' '.$champ->idCss.' '.$classPlg,
									 'id' => $champ->idCss,
									 'title' => html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8"),
									 'value' => !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : "",
									 'rows' => $type->type == 'Textarea' ? $champ->tailleRow : '',
									 'readonly' => $readonly,
									 'disabled' => $disabled,
									 'data-formule' => $champ->formule ? substr($champ->formule, 0, -1) : "",
									 'data-id' => $champ->id,
									 'placeholder' => ($type->type == 'Textarea' && trim($conf->txtPlaceholderTextarea) != '') ? $conf->txtPlaceholderTextarea : ($champ->idType == 2 ? $dateFormat : ''),
									 'data-parent' => $champ->idParent > 0 ? $champ->idParent : '',
									 'data-parentname' => $champ->parent ? $champ->parent->equivalentSql : '',
									 'data-nature' => $champ->nature,
									 'data-unite' => $champ->uniteDuree ? $champ->uniteDuree : '',
									 'data-css' => $champ->styleCss,
									 'data-champcommun' => $champ->idChampCommun > 0 ? $champ->idChampCommun : '',
									 'data-preval' => !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : "",
									 'data-sourceliste' => $champ->sourceListe,
									 'data-idformulaire' => $champ->idFormulaire,
									 'data-codemodele' => ($champ->idType == 22 && $modeleDoc) ? $modeleDoc->code : '',
									 'data-nomxml' => $champ->nomXML ?  $champ->nomXML : '',
								);

								// rendre les champ dupliquer en read only pour éviter tout changement parce que dans valeur_dynamiques on enregistre que l'oririginal
								//if ($champ->idParent>0) $attributes['readonly'] = 'readonly';

								if ($isCatalogue) {
									$attributes['data-idcatalogue'] = $idCatalogue ? $idCatalogue : '';
									$attributes['data-idtypecatalogue'] = $idTypeCatalogue;
									$attributes['data-idresa'] = $idResa ? $idResa : '';
									$attributes['data-iddp'] = $idDp ? $idDp : '';
								}

								// if (is_numeric($champ->sourceListe)) { // }
								if ($champ->sourceListe != "") {
									// On cherche si le champ est rélié à un autre champ
									$champsAssociation = $this->getTableObjet('champs_association')
									->select(array(
										'idChamp1' => (int) $champ->id,
										// 'idFormulaire' => (int) $champ->idFormulaire
									))
									->toArray();

									// On indique que ce champ est lié au champ de la bdd
									$champLinkedTo = "";
									if (count($champsAssociation) > 0) {
										$res = [];
										for ($i = 0; $i < count($champsAssociation); $i++) {
											$res[] = $champsAssociation[$i]['idChamp2'];
										}
										$champLinkedTo = implode("-", array_unique($res));
									}

									$attributes['data-id-select'] = $champ->id;
									$attributes['data-linked-to'] = $champLinkedTo;
								}

								if ($champ->size != "" && $champ->size > 0) {
									$attributes['maxlength']	= $champ->size;
								}
								if ($champ->equivalentSql == 'nomResidence' && $residenceDeCampagne) {
									$attributes['data-idresidence'] = $residenceDeCampagne->id;
								}

								//si logementChefFamille on cherche le chef de famille si existe pour ce ménage et on récup son logement
								if($champ->equivalentSql == 'logementChefFamille' && !empty($sessData['idMenage']) && $sessData['idMenage'] > 0) {
									$logeFDF = $this->getLogementTable()->getLogementChefFamille($sessData['idMenage']);
									if($logeFDF) {
										$sessData[$champ->equivalentSql] = $logeFDF->nom;
										$attributes['value'] = $logeFDF->nom;
									}
									$attributes['readonly'] = true;

								}


								/* pour les champs de type multiple select il faut rajouter l'attribut multiple et la classe multiple et changer le type en select car Multiple-Select n'existe pas*/
								// https://webdevdesigner.com/q/multiselect-in-zend-framework-2-401426/
								$typeChampForm = $type->type;
								$formName = $champ->equivalentSql;

								$attributes['data-itemsRequiredToActivateSelect'] = "NULL";
								if ($champ->idType == 3 || $champ->idType == 18) {
									$attributes['data-itemsRequiredToActivateSelect'] = $champ->itemsRequiredToActivateSelect2;
								}

								if ($champ->idType == "5" || $champ->idType == "12" || $champ->idType == "2" || $champ->idType == "19") {
									$attributes['data-id'] = $champ->id;
								}

								$attributes['data-idtype'] = $champ->idType;

								if ($champ->idType == "13" || $champ->idType == "19") {
									if ($champ->formule && $champ->formule != "") {
										if ($champ->idType == "19") {
											//$attributes['disabled'] = "disabled";
										}
										$attributes['readonly'] = "readonly";
										$attributes['data-formule'] = $champ->formule ? substr($champ->formule, 0, -1) : "";
									}
								}

								if ($champ->idType == 18) {
									$attributes['multiple'] = 'multiple';
									$attributes['class'] .= 'multiple';
									$typeChampForm = "Select";
									$formName .= "[]";
								}

								$formRowToAdd = array(
									'name' => $formName,
									'type' => $typeChampForm,
									'options' => array(
										'label' => $libelle,
										'empty_option' => html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8"),
										'value_options' => $options,
										'label_attributes' => array('class' => 'editable',
																	'data-msgid' => $lmsgid, 'data-changed' => "0",
																	'data-title' => html_entity_decode($translator->translate($imsgid), ENT_NOQUOTES, "UTF-8"),
																	),
									),
									'attributes' => $attributes,
								);
								$form->add($formRowToAdd);
							} catch (\Exception $ex) {
								syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formAdd Exception=".$ex->getMessage());
							}
							try {
								// récupération de la valeur par défaut
								$defaultValueSelect = null;
								if ($idResa) {
									$defaultValueSelect = $this->getTableObjet('valeurs_dynamiques')
									->select(array('idReservation' => $idResa, 'idLocataire' => $idLocataire, 'idChamp' => $champ->id))->current();
								} elseif ($idDp) {
									$defaultValueSelect = $this->getTableObjet('valeurs_dynamiques')
									->select(array('idDp' => $idDp, 'idLocataire' => $idLocataire, 'idChamp' => $champ->id))->current();
								}

								if ($champ->idType == 18) {
									// var_dump($idDp);
									// var_dump($idLocataire);
									// var_dump($champ->id);

									if ($defaultValueSelect) {
										$defaultValue = explode(",", $defaultValueSelect->valeur);
										$form->get($formName)->setValue($defaultValue);
									}
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formSetValue Exception=".$ex->getMessage());
							}

							try {
								$listOptions = [];
								if (count($options) > 0) {
									foreach ($options as $keyO => $option) {
										/// Liaison entre valeurs de chaque champ
										$val2Linked = [];
										$attr = array();
										if(is_array($option)){
											$keyO = $option['value'];
											$attr = $option['attributes'];
											$option = $option['label'];
										}
										if (count($champsAssociation) > 0) {
											foreach ($champsAssociation as $key => $row) {
												if ($row['idVal1'] == $keyO) {
													$val2Linked[] = $row['idVal2'];
												}
											}
										}
										

										// Liste des valeurs du champs 2 lesquels sont réliés chaque option du val1
										$val2Linked = count($val2Linked) > 0 ? implode("-", array_unique($val2Linked)) : "";

										// Possibilité de dévalider certaines options des select
										$disabledOption	= ($disabledOptions && in_array($keyO, $disabledOptions));

										$attr['data-val-linked'] = $val2Linked;
										$listOptions[] = array(
											'value' => $keyO,
											'label' =>(string)$option,
											'disabled' => $disabledOption,
											'attributes' => $attr,
										);
									}
								}

								// if ($formName == "idNationalite") {
								// 	var_dump($listOptions);die();
								// }

								if (count($listOptions) > 0) {
									$form->get($formName)->setAttribute('options', $listOptions);
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formSetAttribute Exception=".$ex->getMessage());
							}

							$champ->extraClass = $classBT.' '.$champ->classCss.' '.$champ->idCss;
						}

						// if ($formName == "idNationalite") {
						// 	$chp = $form->get($champ->equivalentSql);
						// 	var_dump($chp);die();
						// }

						$allFields[$champ->id] = $champ;
					}
				} else {
					$allFields[$champ->id] = $champ;//pas de type html
				}
			}//FIN foreach champs

			// echo "<pre>";
			// var_dump($champsActionsParCondition);
			// echo "</pre>";
			// die();
			//print_r($champsActionsParCondition['required']);exit();

			## ACTION CONDITIONS
			//print_r($idsChampsActions);exit();
			if (!empty($champsActionsParCondition)) {
				//print_r($champsActionsParCondition['required']);exit();
				// print_r($champsActionsParCondition);die();
				foreach ($idsChampsActions as $idChamp) {
					$champRow = !empty($allFields[$idChamp]) ? $allFields[$idChamp] : null;
					//verification si l element existe dans le form

					if ($champRow) {
						if (!empty($champsActionsParCondition['hide']) && in_array($champRow->id, $champsActionsParCondition['hide'])) {
							$champRow->extraClass = str_replace('hide', '', $champRow->extraClass);
							$champRow->extraClass .= ' hide';

							$champRow->classCss = str_replace('hide', '', $champRow->classCss);
							$champRow->classCss .= ' hide';
							try {
								$form->get($champRow->equivalentSql)->setAttribute('class', $champRow->extraClass);
							} catch (\Exception $ex) {
							}
						}
						if (!empty($champsActionsParCondition['show']) && in_array($champRow->id, $champsActionsParCondition['show'])) {
							$champRow->extraClass = str_replace('hide', '', $champRow->extraClass);

							$champRow->classCss = str_replace('hide', '', $champRow->classCss);
							try {
								$form->get($champRow->equivalentSql)->setAttribute('class', $champRow->extraClass);
							} catch (\Exception $ex) {
							}
						}
						//traitement action sur les valeurs de listes
						if (($champRow->idType == 3 || $champRow->idType == 18) && !empty($champsActionsParCondition['liste']) && array_key_exists($champRow->id, $champsActionsParCondition['liste'])) {
							$valeursSelect = $champsActionsParCondition['liste'][$champRow->id]['valeursSelect'];
							$defaultListeMode = $champsActionsParCondition['liste'][$champRow->id]['defaultListeMode'];

							try {
								$options = $form->get($champRow->equivalentSql)->getValueOptions();
								$options = $tools->filtreListe($options, $valeursSelect, $defaultListeMode);
								$form->get($champRow->equivalentSql)->setAttribute('options', $options);
							} catch (\Exception $ex) {
							}
						}

						if (!empty($champsActionsParCondition['required']) && in_array($champRow->id, $champsActionsParCondition['required'])) {
							$champRow->obligatoire = 1;
						}

						$champRow->classCss = $champRow->classCss;
						$allFields[$idChamp] = $champRow;
					}
				}
			}
			## FIN ACTIONS

			$session->allFields = $allFields;

			//on ajoute des champs caché, pour le cas ou on cree une resa manuelle
			$idLogement = "";
			if (!empty($params)) {
				$idLogement = $params['idLogement'];
			}

			$form->add(array(
				 'name' => 'btSubmit_'.$formRow->id,
				 'type' => 'Submit',
				 'attributes' => array(
					 'value' => $translator->translate('b_etape_Valider'),
					 'id' => 'submitbutton_'.$formRow->id,
					  'class' => 'btn btn-md btn-block pull-right',
				 'title' => $translator->translate('b_etape_Valider'),
			),
			));



			if ($loc) {
				//fusion loc
				if ($idResa) {
					if (!$returnGetReservationPms) {
						$returnGetReservationPms = $this->getReservationPms($idResa);
					}

					// unset($returnGetReservationPms['loc']->idNationalite);
					// unset($returnGetReservationPms['loc']->idNationalite);
					// unset($returnGetReservationPms['locArray']['idNationalite']);
					// echo "<pre>";var_dump($returnGetReservationPms);echo "</pre>";die();

					if (!empty($returnGetReservationPms) && !empty($returnGetReservationPms['loc'])) {
						$loc = $returnGetReservationPms['loc'];
					}
				}

				if (is_object($loc)) {
					$form->bind($loc);
				}
			}

			syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idForm=".$formRow->id." nameForm=".$formRow->name." Fin");
			$isResaManuelle = false;
			if (!empty($locAllInfosObj)) {
				$form->setData($locAllInfosObj);
				$sessData = $locAllInfosObj;
			}
			if (!empty($params)) {
				$form->setData($params);
				$isResaManuelle = true;
			}

			$maxCols = !empty($cols) ? max($cols) : 0;
			//on stock chaque form avec ses data dans un array
			$formulaires[] = $formRow;
			$formsArray[$formRow->id] = $form;
			$formsAllFields[$formRow->id] = $allFields;
			$formsCols[$formRow->id] = $maxCols;
			$formsDateFields[$formRow->id] = $dateFields;
			$formNumRows[$formRow->id] = !empty($numRows) ? max($numRows) : 0;

			$formActions[$formRow->id] = $actionOnCheck;
		}//FIN foreach formulaires
		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa : Actions 2 Fin");

		$session->docsFields = $docsFields;
		$session->formulaires = $formulaires;
		$session->formsAllFields = $formsAllFields;

		// echo "<pre>";
		// var_dump($champsActionsParCondition);
		// echo "</pre>";
		// die();

		// Partie cartes Salto
		$tableCartes = $this->getTableObjet('cartes');
		$selectCarte = $tableCartes->getSql()->select();
		$selectCarte->where(array('idLocataire' => $idLocataire));
		$selectCarte->order(array('dateCreation DESC'));
		$lastCarte = $tableCartes->selectWith($selectCarte)->current();
		$allCartesLoc = $this->getTableObjet('cartes')->select(array('idLocataire' => $idLocataire))->toArray();

		//liste de residences pour changement de logement
		$residences =  $this->getResidencesTable()->fetchByGest($gestId);

		## choix type logement Base
		$choixTypeLogementBase = array();
		if ($modeChoix == 'typeLogementBase' && $idResa) {
			for ($i = 1; $i <= $maxChoix; $i++) {
				$choixRow = $this->getChoixTable()->fetchBy(array('idReservation' => $idResa, 'numeroChoix' => $i))->current();
				if ($choixRow) {
					$choixTypeLogementBase[$i]	= [ 'idResidence' => $choixRow->idResidence, 'idTypeLogement' => $choixRow->idTypeLogement ];
				}
			}
		}

		syslog(LOG_INFO, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa avantViewModel");
		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/extraform')
			->setVariables(array(
					'forms' => $formsArray,
					'allForms' => $formulaires,
					'cols' => $formsCols,
					'langue' => $langue,
					'typesTable' => $typeChampsTable,
					'allFields' => $formsAllFields,
					'champsDate' => $formsDateFields,
					'docsFields' => $docsFields,
					'actionOnCheck' => $formActions,
					'sessData' => $sessData,
					'typesLogement' => $typesLogement,
					'idCamp' => $idCamp,
					'champsDeCriteres' => $champsDeCriteres,
					'numRows' => $formNumRows,
					'maxChoix' => $maxChoix,
					'minChoix' => $minChoix,
					'modeChoix' => $modeChoix,
					'ordreChoix' => $ordreChoix,
					'datesPlage' => $datesPlage,
					'prog' => $progamme,
					'loc' => $loc,
					'idResa' => $idResa,
					'idDp' => $idDp,
					'isResaManuelle' => $isResaManuelle,
					'idProgramme' => $idProgramme,
					'idSousProgramme' => $idSousProgramme,
					'idLogement' => $idLogement,
					'couleurAccordion' => $couleurAccordion,
					'idLogementResa' => !empty($sessData['idLogement']) ? $sessData['idLogement'] : 0,
					'idResaADupliquer' => $idResaADupliquer,
					'formsCatDocs' => $formsCatDocs,
					'formsSuivis' => $formsSuivis,
					'idOngletFormulaire' => $idOngletFormulaire,
					'conf' => $conf,
					'residences' => $residences,
					'lastCarte' => $lastCarte,
					'allCartesLoc' => $allCartesLoc,
					'choixTypeLogementBase' => $choixTypeLogementBase,
					'modeCampagne' => $modeCampagne,
					'memeUsager' => $memeUsager,
					'campagneType' => $campagneType,
					'resa'	=> $resa,
					'champEtatReservation' => $champEtatReservation,
					'creationNouveauDossier' => $creationNouveauDossier,
		));

		$htmlForm = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire=$idLocataire idResa=$idResa idDp=$idDp Fin lenHtmlForm=".strlen($htmlForm));
		return $htmlForm;
	}

	public function actifCarteAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isPost()) {
			$idLocataire = $request->getPost('idLoc');
			$idCarte = $request->getPost('idCarte');
			$actifCarte = $request->getPost('actifCarte');

			// Message de retour
			$success = false;
			$msg = '';
			$htmlOP = '';

			if ($idLocataire && $idCarte) {
				$apiSig = $this->getTableObjet('api_sig')->select(array('className' => 'SALTO', 'active' => '1'))->current();

				// Si actifCarte = '1' => désactiver la carte
				// Si actifCarte = '0' => activer la carte
				if ($actifCarte == "1") {
					$carteUpdated = $this->getTableObjet('cartes')->update(array('actif' => '0', 'dateDesact' => date('Y-m-d H:i:s')), array('id' => (int) $idCarte));
					$msgLog = "BO-Fiche Usager - Désactivation carte ".$idCarte;
					$msg = "Carte désactivée";
					$newColor = "red";
					$newTitle = "Activer la carte";
					$tdDateDesac = date('Y-m-d H:i:s');

					// Insert into pile sig suppression de la cartes
					$this->getTableObjet('pile_sig')->insert(array(
						'idLocataire' => $idLocataire,
						'idApiSIG' => $apiSig->id,
						'dateCreation' => date('Y-m-d H:i:s'),
						'flag' => 'chgtSupport',
					));
				} else {
					$carteUpdated = $this->getTableObjet('cartes')->update(array('dateCreation' => date('Y-m-d H:i:s'), 'actif' => '1', 'dateDesact' => null), array('id' => (int) $idCarte));
					$msgLog = "BO-Fiche Usager - Activation carte ".$idCarte;
					$msg = "Carte activée";
					$newColor = "green";
					$newTitle = "Désactiver la carte";
					$tdDateDesac = "-";

					// Insert into pile sig activation de la cartes
					$this->getTableObjet('pile_sig')->insert(array(
						'idLocataire' => $idLocataire,
						'idApiSIG' => $apiSig->id,
						'dateCreation' => date('Y-m-d H:i:s'),
						'flag' => 'activeCarte',
					));
				}

				if ($carteUpdated) {
					$success = true;

					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = $msgLog;
					$log->tableName = "cartes";
					$log->idLocataire = (int) $idLocataire;
					$this->getLogsTable()->saveLogs($log);
				} else {
					$msg = 'Problème lors de la MAJ de la carte';
				}
			} else {
				$msg = 'idLocataire ou idCarte manquant';
			}
			return new JsonModel(array('success' => $success, 'msg' => $msg, 'newColor' => $newColor, 'newTitle' => $newTitle, 'tdDateDesac' => $tdDateDesac, 'idactif' => $idactif));
		}
		exit();
	}

	## script pour exporter le corps des email en fichiers
	public function exporterhistomailAction()
	{
		$mailRows = $this->getHistoriquemailTable()->getMailsToConvert();
		$tools = new Tools();
		$i = 0;

		foreach ($mailRows as $mail) {
			$modele = $this->getModelesmailTable()->getModele($mail->idModele);
			$pdfPath = "";
			if ($mail->pdf) {
				$loc = $this->getLocatairesTable()->getLocataire($mail->idLocataire);
				$pdfCorp = $mail->pdf;
				$pdfHeader = $mail->pdfHeader;
				$pdfFooter = $mail->pdfFooter;
				$name = "pj_".$this->removeAccent($modele->nomModele);
				$file = $this->genererPdfHistorique($loc, $pdfCorp, $pdfHeader, $pdfFooter, $name);
				$filename = pathinfo($file, PATHINFO_FILENAME);
				$pdfPath = getcwd().'/public/docs/pj/tmp/'.$loc->id.'/'.$filename.'.pdf';
			}
			$tools->saveMailEnHTML($mail->idLocataire, $mail->message, $modele->nomModele, $pdfPath, $mail->id);//fileToDelete => pdf
			// echo $mail->idLocataire."<br>";
			if ($pdfPath) {
				$this->deleteFile($pdfPath);
			}
			$i++;
			$mail->message = $mail->pdf = $mail->pdfHeader = $mail->pdfFooter = null;
			$this->getHistoriquemailTable()->save($mail);
		}
		echo "$i lignes";
		exit();
	}



	public function genererpdfAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$href = "";
			$id = $request->getPost('id');
			$mail = $this->getHistoriquemailTable()->getHistorique($id);
			if ($mail) {
				$file = getcwd()."/public/docs/locataires/".$mail->idLocataire."/mailing/".$id."/pdf.pdf";
				if (file_exists($file)) {
					$doc = "/docs/locataires/".$mail->idLocataire."/mailing/".$id."/pdf.pdf";
					$modele = $this->getModelesmailTable()->getModele($mail->idModele);
					$name = "pj_".$this->removeAccent($modele->nomModele);
					$href = $doc;
				} else {
					$loc = $this->getLocatairesTable()->getLocataire($mail->idLocataire);
					$pdfCorp = $mail->pdf;
					$pdfHeader = $mail->pdfHeader;
					$pdfFooter = $mail->pdfFooter;
					$modele = $this->getModelesmailTable()->getModele($mail->idModele);
					$name = "pj_".$this->removeAccent($modele->nomModele);
					$file = $this->genererPdfHistorique($loc, $pdfCorp, $pdfHeader, $pdfFooter, $name);
					$filename = pathinfo($file, PATHINFO_FILENAME);
					$href = '/docs/pj/tmp/'.$loc->id.'/'.$filename.'.pdf';
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						  'href' => $href,
						  'id' => $id,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function creerresaAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$locForm = new LocataireForm();
		$resaForm = new ResaForm();

		if ($request->isXmlHttpRequest()) {
			$id = $request->getPost('id');
			$idLogement = $request->getPost('idRessource');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			if (!$id) {
				//ajout
				$id = 0;
				$idLocataire = 0;
			}


			############################## PARTIE FICHE LOCATAIRE #####################
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire);

			$allPays =  $this->getPaysTable()->fetchAll();
			$paysOption = array();
			$natOption = array();
			foreach ($allPays as $pays) {
				$paysOption[$pays->id] = $pays->pays;
				$natOption[$pays->id] = $pays->nationalite;
			}

			$locForm->get('idPays')->setAttribute('options', $paysOption);
			$locForm->get('idNationalite')->setAttribute('options', $natOption);
			//Liste des programmes
			$progs = $this->getProgrammeTable()->getProgrammesParent();
			$progList = array();
			foreach ($progs as $p) {
				$progList[$p->id] = $p->nom;
			}
			asort($progList);

			$locForm->get('idProgramme')->setAttribute('options', $progList);

			//sous prog
			$sp = array();
			if ($loc->idProgramme > 0) {
				$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
				//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

				if ($result->count() <= 0) {
					$result = $this->getProgrammeTable()->getProgrammeById($loc->idProgramme);

					$sp[$result->id] = $result->nom;
				} else {
					foreach ($result as $r) {
						$sp[$r->id] = $r->nom;
					}
				}
			} else {
				$sp = false;
			}

			if (!empty($sp)) {
				asort($sp);
				$locForm->get('idSousProgramme')->setAttribute('options', $sp);
			}


			if ($loc) {
				$locForm->bind($loc);
				$dateNaissance = ($loc->dateNaissance && substr($loc->dateNaissance, 0, 2) != '00') ? date('d-m-Y', strtotime($loc->dateNaissance)) : "";
				$locForm->get('dateNaissance')->setValue($dateNaissance);
			}

			$etats = $this->getTableObjet('etat_reservation')->select();
			$etatOption = array();
			foreach ($etats as $row) {
				$etatOption[$row->id] = $row->nom;
			}


			############################## VIEW RENDERGIN LOC ########################

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/creerresa')
			->setVariables(array(
					'form' => $locForm,
					'etatResa' => $etatOption,
					'isGoal' => $loc->codeGoal ? 1 : 0,
					'lang' => 'fr_FR',
					'idLogement' => $idLogement,
					'dateDebut' => $dateDebut ? $dateDebut : "",
					'dateFin' => $dateFin ? $dateFin : "",
			));

			$htmlOutputLoc = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);



			$htmlOutput = $loc;
			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutputLoc,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function getDuree($idResa, $idEtat, $exclureICResa = false)
	{
		##on verifie quel niveau est activé, selon cette ordre de priorité:
		### 1 : Campagne
		### 2 : Type logement
		### 3 : Batiment
		### 4 : Residence
		### 5 : Systeme
		$niveauCampagne = $niveauTypeLogement = $niveauBatiment = $niveauResidence = null;

		$tableEtat = $this->getEtatIntercontratTable();
		$etatSysteme = $tableEtat->select(array('id' => $idEtat))->current();
		$duree = $etatSysteme->duree;

		$resa = $this->getResaTable()->getResa($idResa);
		if ($resa) {
			## Niveau campagne
			if ($resa->idCampagne) {
				$niveauCampagne = $this->getEtatintercontratconfigTable()->getNiveauActive($idEtat, "campagne", $resa->idCampagne);
			}

			## Niveau Type logement
			$niveauTypeLogement = $this->getEtatintercontratconfigTable()->getNiveauActive($idEtat, "typelogement", $resa->idTypeLogementAttribue);

			## Niveau Batiment
			$logement = $this->getLogementTable()->getLogement($resa->idLogement);
			if ($logement) {
				$niveauBatiment = $this->getEtatintercontratconfigTable()->getNiveauActive($idEtat, "batiment", $logement->idBatiment);
				## Niveau Residence
				$batiment = $this->getBatimentTable()->getBatiment($logement->idBatiment);
				if ($batiment) {
					$niveauResidence = $this->getEtatintercontratconfigTable()->getNiveauActive($idEtat, "residence", $batiment->idResidence);
				}
			}

			if ($niveauCampagne) {
				$duree = $niveauCampagne->duree;
			} elseif ($niveauTypeLogement) {
				$duree = $niveauTypeLogement->duree;
			} elseif ($niveauBatiment) {
				$duree = $niveauBatiment->duree;
			} elseif ($niveauResidence) {
				$duree = $niveauResidence->duree;
			}
			//duree alongé en dur pour une etat donnée
			if (!$exclureICResa) {
				//$rowIC = $this->getTableObjet('intercontrat')->select(array('idReservation'=>$idResa,'idEtat'=>$idEtat))->current();
				$tableIC = $this->getTableObjet('intercontrat');
				$select = $tableIC->getSql()->select();
				$select->where(array('idReservation' => $idResa, 'idEtat' => $idEtat));
				$select->order(array('dateEtat DESC'));
				$rowIC = $tableIC->selectWith($select)->current();
				if ($rowIC && $rowIC->duree != $duree) {
					$duree = $rowIC->duree;
				}
			}
		}

		return $duree ? $duree : 0;
	}

	private function getEtatsPrecedente($idEtat)
	{
		//$idEtat, on calcule les etat precedente a cette etat
		$allEtat = $this->getAllEtatIC();
		$etatPrev = array();
		foreach ($allEtat as $etat) {
			if ($etat->id == $idEtat) {
				return $etatPrev;
			}
			$etatPrev[] = $etat;
		}
		return $etatPrev;
	}

	private function getEtatsSuivante($idEtat)
	{
		//$idEtat, on calcule les etat precedente a cette etat
		$allEtat = $this->getAllEtatIC();
		$etatPrev = array();
		$i = 0;
		$idCourant = 0;
		$rows = array();
		foreach ($allEtat as $etat) {
			if ($etat->default != 1) {
				$rows[$i] = $etat;
				if ($etat->id == $idEtat) {
					$idCourant = $i;
				}
				$i++;
			}
		}
		$etatSuivante = array();
		for ($i = $idCourant + 1; $i < sizeof($rows);$i++) {
			$etatSuivante[] = $rows[$i];
		}
		return $etatSuivante;
	}

	// ajout de l'etat intercontrat dans la table intercontrat
	private function ajouterEtatIntercontrat($idResa, $dateValidationIC, $type = "", $commentaire = null, $idEtatChoisi = 0)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa dateValidationIC=$dateValidationIC type=$type idEtatChoisi=$idEtatChoisi");
		$resa =  $this->getResaTable()->getResa($idResa);

		$idEtatCourante = $resa->idIntercontrat;
		$tableIC = $this->getIntercontratTable();
		$tableEtat = $this->getEtatIntercontratTable();
		$allEtat = $this->getAllEtatIC();
		$idReservation = $resa->id;

		$firstEtatIC = $this->getPremierEtatIC();

		$totalDuree = 0;
		/*foreach($allEtat as $etat){
			if($etat->id == $idEtatCourante){
				//break
				break;
			}else{
				//on calcule les durée
				$row = $tableIC->select(array('idReservation'=>$idReservation,'idEtat'=>$etat->id))->current();
				if($row){
					$duree = $row->duree;
				}else{
					$duree = $this->getDuree($idReservation, $etat->id);

				}
				$totalDuree += $duree;
			}
		}*/
		/*$dateFinSejour = date('Y-m-d',strtotime($resa->dateDepart." + 1 day"));
		$dateFinSejourTS = strtotime($dateFinSejour);

		$dateFSPlusTotalPeriodes = date('Y-m-d',strtotime($dateFinSejour." + $totalDuree day"));
		$dateFSPlusTotalPeriodesTS = strtotime($dateFSPlusTotalPeriodes);


		$dateValidationICTS = strtotime($dateValidationIC);

		$dureeEncours = $dateValidationICTS - $dateFSPlusTotalPeriodesTS;

		$dateDebut = new \DateTime($dateFSPlusTotalPeriodes);
		$dateFin = new \DateTime($dateValidationIC);
		$difference = $dateDebut->diff($dateFin);
		$duree = $difference->format('%a');*/

		if (!$dateValidationIC) {
			$dateValidationIC = date('Y-m-d');
		} else {
			$dateValidationIC = date('Y-m-d', strtotime($dateValidationIC));
		}

		//on cherche la date de l etat précedente puis on fait dat dateValidationIC - date etatprecedente = duree
		//$prevEtat = $this->getPrevEtatIC($idEtatCourante);
		//idEtatCourante = etat precedente qu on vient de valider
		$prevEtat = $this->getEtatIntercontratTable()->select(array('id' => $idEtatCourante))->current();
		//premiere etat
		/*if($prevEtat->id == $idEtatCourante){
			$dateEtatPrecedente = $resa->dateDepart;
		}else{ */
		if ($prevEtat) {
			$select = $tableIC->getSql()->select();
			$select->where(array('idReservation' => $idReservation, 'idEtat' => $prevEtat->id));
			$select->order(array('dateEtat DESC'));
			$etatPrecedente = $tableIC->selectWith($select)->current();
			//$etatPrecedente = $tableIC->select(array('idReservation'=>$idReservation,'idEtat'=>$prevEtat->id))->current();
		} else {
			$etatPrecedente = $tableIC->select(array('idReservation' => $idReservation))->current();
		}

		if ($etatPrecedente) {
			$dateEtatPrecedente = $etatPrecedente->dateEtat;
		} else {
			$dateEtatPrecedente = $resa->dateDepart;
		}
		//}

		$datePrev = new \DateTime($dateEtatPrecedente);
		$dateActuel = new \DateTime($dateValidationIC);
		$difference = $datePrev->diff($dateActuel);
		$duree = $difference->format('%a');
		//echo "dateEtatPrecedente = $dateEtatPrecedente , dateValidationIC = $dateValidationIC";exit();

		//on calcule le retard
		$configDuree = $this->getDuree($idReservation, $idEtatCourante);
		$decalage = $configDuree - $duree;

		//echo "duree : $configDuree - $duree = $decalage";exit();

		//on vérifie si etat intercontrat existe déjà dans la table intercontrat
		//$etatDeResa = $tableIC->select(array('idReservation'=>$idReservation,'idEtat'=>$idEtatCourante))->current();
		$select = $tableIC->getSql()->select();
		$select->where(array('idReservation' => $idReservation, 'idEtat' => $idEtatCourante));
		$select->order(array('dateEtat DESC'));
		$etatDeResa = $tableIC->selectWith($select)->current();
		$isNewEtat = false;//si on ajoute la premiere etat on doit pas ajouter la prochane, que si on valide la premiere
		//print_r($idEtatCourante);exit();
		//print_r($etatDeResa);exit();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($idEtatChoisi > 0) {
			$nextEtat = $tableEtat->select(array('id' => $idEtatChoisi))->current();
		} else {
			$nextEtat = $this->getNextEtatIC($idEtatCourante);
		}

		//on verifie si l etat suivante n a pas ete deja ajouté, par un autre user par exemple
		if ($nextEtat->id == $resa->idIntercontrat && $resa->idIntercontrat != $firstEtatIC->id) {
			return false;
		}

		if ($etatDeResa) {

			//update
			if ($type == "valider") {
				//$tableIC->update(array('duree'=>$duree,'decalage'=>$decalage,'valide'=>'0'),array('id'=>$etatDeResa->id));
			} else {
				$tableIC->update(array('duree' => $duree, 'decalage' => $decalage, 'valide' => '1', /*'commentaire'=>$commentaire, 'creation_date' => date('Y-m-d H:i:s'), 'userid'=>$gestId*/), array('id' => $etatDeResa->id));
				//on passe en valide les etat avant
				$etatICDeResa = $tableIC->select(array('idReservation' => $idReservation));
				foreach ($etatICDeResa as $er) {
					if ($er->id < $etatDeResa->id && $er->valide != '1') {
						$tableIC->update(array('valide' => '1'), array('id' => $er->id));
					}
				}

				$log = new Logs();

				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->dataBefore = $etatDeResa;
				$log->dataAfter = $tableIC->select(array('id' => $etatDeResa->id))->current();
				$log->tableName = "Inter-contrat";
				$log->operation = "Inter-contrat : validation etat ".$prevEtat->nom." de la reservation ".$idReservation;
				$log->idReservation = $idReservation;
				$log->idLocataire = $resa ? $resa->idLocataire : null;
				$this->getLogsTable()->saveLogs($log);
			}
		} else {

			//ajout
			$firstEtat = $this->getPremierEtatIC();
			if ($firstEtat->id == $nextEtat->id) {
				$isNewEtat = true;
				$dec = 0;
				$valid = '0';
				$dur = $configDuree;
				$oper = "Inter-contrat : ajout premiere etat ".$prevEtat->nom." de la reservation ".$idReservation;
			} else {
				$dec = $decalage > 0 ? $decalage : 0;
				$valid = '1';
				$dur = $configDuree;
				$oper = "Inter-contrat : ajout etat ".$prevEtat->nom." de la reservation ".$idReservation;
			}

			$data = array('idEtat' => $idEtatCourante,
								'idReservation' => $idReservation,
								'duree' => $dur,
								'decalage' => $dec,
								'valide' => $valid,
								'dateEtat' => $dateValidationIC,
								'commentaire' => $commentaire,
								'creation_date' => date('Y-m-d H:i:s'),
								'userid' => $gestId,
								);
			$tableIC->insert($data);

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->dataBefore = array();
			$log->dataAfter = $data;
			$log->tableName = "Inter-contrat";
			$log->operation = $oper;
			$log->idReservation = $idReservation;
			$log->idLocataire = $resa ? $resa->idLocataire : null;
			$this->getLogsTable()->saveLogs($log);
		}

		//on ajout l etat suivante , si differente de dispo: defautl =1
		//$nextEtat = $this->getNextEtatIC($idEtatCourante);

		//if($nextEtat->default != 1 && !$isNewEtat && $type != "annuler"){ // }
		if (!$isNewEtat && $type != "annuler") {
			$data = array('idEtat' => $nextEtat->id,
								'idReservation' => $idReservation,
								'duree' => $nextEtat->duree,
								'decalage' => 0,
								'valide' => '0',
								'dateEtat' => $dateValidationIC,
								'commentaire' => $commentaire,
								'creation_date' => date('Y-m-d H:i:s'),
								'userid' => $gestId,
								);
			if ($nextEtat->default == 1) {
				$data['valide'] = '1';
			}
			$tableIC->insert($data);
			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->dataBefore = array();
			$log->dataAfter = $data;
			$log->tableName = "Inter-contrat";
			$log->operation = "Inter-contrat : ajout nouvelle etat ".$nextEtat->nom." de la reservation ".$idReservation;
			$log->idReservation = $idReservation;
			$log->idLocataire = $resa ? $resa->idLocataire : null;
			$this->getLogsTable()->saveLogs($log);
		}
		//exit();
		return $duree;
	}


	public function validerintercontratAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idReservation = (int) $request->getPost('idReservation');

			$idCurrent = (int) $request->getPost('currentStatut');
			$idEtatArray = $request->getPost('idEtat');
			$dureeArray = $request->getPost('duree');
			$decalageArray = $request->getPost('decalage');

			$tableIC = $this->getIntercontratTable();
			$tableEtat = $this->getEtatIntercontratTable();

			$allStatut = $this->getAllEtatIC();
			$oldStatutRes = $tableIC->select(array('idReservation' => $idReservation, 'valide' => '0'))->current();
			$oldStatut = 0;
			if ($oldStatutRes) {
				$oldStatut = $oldStatutRes->idEtat;
			}

			for ($i = 0; $i < sizeof($idEtatArray); $i++) {
				$idEtat = $idEtatArray[$i];
				$duree = $dureeArray[$i];
				//$decalage = $decalageArray[$i];
				$etatSysteme = $tableEtat->select(array('id' => $idEtat))->current();
				//on cherche le niveau de config activé
				$configDuree = $this->getDuree($idReservation, $idEtat);
				$decalage = $configDuree - $duree;

				$statutDeResa = $tableIC->select(array('idReservation' => $idReservation, 'idEtat' => $idEtat))->current();
				if ($statutDeResa) {

					//tracabilite
					$statut = $tableIC->select(array('idReservation' => $idReservation, 'idEtat' => $idEtat))->current();
					$etat = $tableEtat->select(array('id' => $idEtat))->current();
					$log = new Logs();

					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "Inter-contrat : changement de statut ".$etat->nom." de la reservation ".$idReservation;
					$log->dataBefore = $statutDeResa;
					$log->dataAfter = $statut;
					$log->tableName = "Inter-contrat";
					$log->idReservation = $idReservation;
					if ($statutDeResa->duree != $duree) {
						if ($statutDeResa->duree != $duree) {
							$log->operation = "Inter-contrat : changement de duree de statut ".$etat->nom." de la reservation ".$idReservation;
							$this->getLogsTable()->saveLogs($log);
						}
					}

					//fin tracabilite
					$allOldStatsRes = $tableIC->select(array('idReservation' => $idReservation));
					$allOldStats = array();
					foreach ($allOldStatsRes as $r) {
						$allOldStats[] = $r;
					}
					## update
					$tableIC->update(array('duree' => $duree, /*'decalage'=>$decalage,*/'valide' => '0'), array('id' => $statutDeResa->id));
					if (($statutDeResa->duree != $duree) && $statutDeResa->dateEtat) {
						//on maj la date des etat suivante
						$etatSuivante = $this->getEtatsSuivante($idEtat);
						if (!empty($etatSuivante)) {
							$dureeAvant = $duree;//duree etat en cours
							$dateAvant = $statutDeResa->dateEtat;
							foreach ($etatSuivante as $icRow) {
								$ic = $tableIC->select(array('idReservation' => $idReservation, 'idEtat' => $icRow->id))->current();
								if ($ic && $ic->dateEtat) {
									$newDate = date('Y-m-d', strtotime($dateAvant." + $dureeAvant day"));
									$tableIC->update(array('dateEtat' => $newDate), array('id' => $ic->id));
									$dureeAvant = $ic->duree;
									$dateAvant = $ic->dateEtat;
								}
							}//end foreach
						}
					}
				} else {
					## insert
					$data = array('idEtat' => $idEtat,
								'idReservation' => $idReservation,
								'duree' => $duree,
								'decalage' => $decalage,
								'dateEtat' => date('Y-m-d'),
								);
					/*$tableIC->insert($data);
					//tracabilite
					$statut = $tableIC->select(array('idReservation'=>$idReservation,'idEtat'=>$idEtat))->current();
					$etat = $tableEtat->select(array('id'=>$idEtat))->current();
					$log = new Logs();

					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "Inter-contrat : changement de statut ".$etat->nom." de la reservation ".$idReservation;
					$log->dataBefore = $statutDeResa;
					$log->dataAfter = $statut;
					$log->tableName = "Inter-contrat";

					$this->getLogsTable()->saveLogs($log);*/
				}
			}

			## current statut
			$changed = false;
			foreach ($allStatut as $etat) {
				if ($etat->id == $idCurrent) {
					break;
				}
				## tracabilite

				if ($oldStatut != $idCurrent && !$changed) {
					$curr = $tableEtat->select(array('id' => $idCurrent))->current();
					$oldEtat = $tableEtat->select(array('id' => $oldStatut))->current();
					$log = new Logs();

					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->dataBefore = $statutDeResa;
					$log->dataAfter = $statut;
					$log->tableName = "Inter-contrat";
					$log->operation = "Inter-contrat : changement de statut ".$oldEtat->nom." par ".$curr->nom." de la reservation ".$idReservation;
					$log->idReservation = $idReservation;
					$this->getLogsTable()->saveLogs($log);
					$changed = true;
				}

				$tableIC->update(array('valide' => '1'), array('idEtat' => $etat->id, 'idReservation' => $idReservation));
			}

			$resa = $this->getResaTable()->getListeById($idReservation)->current();
			$htmlOPIC = $this->loadIntercontratTab($resa);

			$view = new JsonModel(array(
						'success' => true,
						'msg' => 'Validation bien faite',
						'htmlOutputIC' => $htmlOPIC,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadIntercontratTab($resa)
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$rows = $this->getIntercontratByResa($resa->id);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/intercontrat')
			->setVariables(array(
				'rows' => $rows,
			));

		$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

		return $htmlOutput;
	}

	private function loadIntercontratTabBackup($resa)
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$stauts = $this->getEtatIC($resa);
		$etatIC = $stauts['etats'];
		$current = $stauts['current'];

		$current = $resa->idIntercontrat;

		## verification si l intercontrat est terminer
		$isIntercontratOver = $this->isIntercontratOver($resa);

		## delai de disponibilite
		/*$now = strtotime(date('Y-m-d'));
		$periode = 0;
		$finSejour = strtotime($row->dateDepart);
		foreach ($etatIC as $etat) {
			$periode += $etat->duree + $etat->decalage;

		}*/


		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/intercontrat')
			->setVariables(array(
			  "etatIC" => $etatIC,
			  "current" => $current,
			  "idReservation" => $resa ? $resa->id : "",
			  "isOver" => $isIntercontratOver,
			));

		$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

		return $htmlOutput;
	}

	private function loadDemandesTab($resa)
	{
		$pendingDemandes = $completedDemandes = null;

		$pendingDemandes = $this->getDemandesByResa($resa->id);
		$completedDemandes = $this->getDemandesByResa($resa->id, true);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/demandesTab')
			->setVariables(array(
				"pendingDemandes" => $pendingDemandes,
				"completedDemandes" => $completedDemandes,
			));

		$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

		return $htmlOutput;
	}

	## lecture des commentaire d'une résa ou Dp par usager ou par dossier selon le paramétrage campagne d'affichage des multisuivis
	private function getCommentaireRows($idResa, $idDp){
		$rows = array();
		$idCampagne = null;
		$idLocataire = 0;
		$resa = null;
		if($idResa){
			$resa = $this->getResaTable()->getResa($idResa);
		}
		if($resa){
			$idCampagne = $resa->idCampagne;
			$idLocataire = $resa->idLocataire;
		} elseif ($idDp) {
			$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			if($dp) $idCampagne = $dp->idCampagne;
			$idLocataire = $dp->idLocataire;
		}
		$modeCamp = null;
		if($idCampagne){
			$modeCamp = $this->getCampagneTable()->getCampagneMode($idCampagne);
		}
		if($modeCamp && $modeCamp->afficherSuivisParIdLocataire == '1'){
			if ($resa) {
				$idsResa = $this->getResaTable()->getIdsResasByLoc($idLocataire);
				$rows = $this->getResaCommentaires($idsResa);
			} elseif ($idDp) {
				$idsDp = $this->getDomiciliationsTable()->getIdsDpByLoc($idLocataire);
				$rows = $this->getDomiciliationsTable()->getDpCommentaires($idsDp);
			}
		}else{
			if ($resa) {
				$rows = $this->getResaCommentaires($resa->id);
			} elseif ($idDp) {
				$rows = $this->getDomiciliationsTable()->getDpCommentaires($idDp);
			}
		}
		
		return $rows;
	}

	private function loadCommentairesTab($resa = null, $idDp = 0)
	{

		$rows = $this->getCommentaireRows($resa ? $resa->id : null ,$idDp);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/commentairesresatab')
		->setVariables(array(
			"rows" => $rows,
			"idResa" => $resa ? $resa->id : 0,
			"idDp" => $idDp,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	public function reloadresacommentairesAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$html = null;
			$idResa = (int) $request->getPost('idResa', 0);
			$idDp = (int) $request->getPost('idDp', 0);
			$rows = $this->getCommentaireRows($idResa ,$idDp);
			foreach ($rows as $row):
				$html .= '<tr>';
				$html .= '<td>'.$row->creation_date.'</td>';
				$html .= '<td>'.$row->commentaire.'</td>';
				$html .= '<td>'.$row->display_name.'</td>';
				$html .= '</tr>';
			endforeach;
		}

		$view = new JsonModel(array(
			'html' => $html,
		));

		$view->setTerminal(true);
		return $view;
	}

	private function getResaCommentaires($idResa)
	{
		$table = $this->getTableObjet('reservations_commentaires');
		$select = $table->getSql()->select();
		$select->join('user', 'user.user_id = reservations_commentaires.userid', array('display_name' => 'display_name'), 'LEFT');
		if(is_array($idResa)){
			$select->where->in('reservations_commentaires.idResa', $idResa);
		}else{
			$select->where(array('reservations_commentaires.idResa' => $idResa));
		}
		$rows = $table->selectWith($select);
		return $rows;
	}

	public function sendresacommentaireAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa', 0);
			$idDp = (int) $request->getPost('idDp', 0);
			$commentaire = $request->getPost('commentaire');
			if ($idResa) {
				$table = $this->getTableObjet('reservations_commentaires');
				$table->insert(array(
					'idResa' => $idResa,
					'commentaire' => $commentaire,
					'userid' => $user->getId(),
					'creation_date' => date('Y-m-d H:i:s', time()),
				));
			} elseif ($idDp) {
				$data = array(
					'idDp' => $idDp,
					'commentaire' => $commentaire,
					'userid' => $user->getId(),
					'creation_date' => date('Y-m-d H:i:s', time()),
				);
				$this->getDomiciliationsTable()->saveDpCommentaire($data);
			}
		}
		$view = new JsonModel(array(
			'success' => 'success',
		));

		$view->setTerminal(true);
		return $view;
	}

	private function getDemandesByResa($idResa, $completed = false)
	{
		$table = $this->getTableObjet('demandes');
		$select = $table->getSql()->select();
		$select->join('demandes_etat', 'demandes_etat.id = demandes.etat', array('etatNom' => 'nom'), 'LEFT');
		$select->join('demandes_modeles', 'demandes_modeles.id = demandes.idModele', array('modeleNom' => 'nom'), 'LEFT');
		$select->join('demandes_type', 'demandes_type.id = demandes_modeles.type', array('typeNom' => 'nom'), 'LEFT');
		$select->where(array('demandes.idResa' => $idResa));
		if ($completed) {
			$select->where->greaterThanOrEqualTo('demandes.etat', 5);
		} else {
			$select->where->lessThan('demandes.etat', 5);
		}
		$rows = $table->selectWith($select);
		$result = array();
		foreach ($rows as $index => $row) {
			$result[$index] = new \stdClass();
			$result[$index]->id = $row->id;
			$result[$index]->creation_date = $row->creation_date;
			$result[$index]->etat = $row->etatNom;
			$result[$index]->type = $row->typeNom;
			$result[$index]->modele = $row->modeleNom;
			$result[$index]->messages = $this->getMessagesByDemande($row->id);
		}
		return $result;
	}

	private function getMessagesByDemande($idDemande)
	{
		$table = $this->getTableObjet('demandes_messages');
		$select = $table->getSql()->select();
		$select->join('user', 'user.user_id = demandes_messages.userid', array('adminName' => 'display_name'), 'LEFT');
		$select->join('locataires', 'locataires.id = demandes_messages.idLocataire', array('locFirstName' => 'prenom', 'locLastName' => 'nom'), 'LEFT');
		$select->where(array('demandes_messages.idDemande' => $idDemande));
		$rows = $table->selectWith($select);
		return $rows;
	}

	private function getCategoriesResident($all = false, $modeDp = false, $idFormulaire = null)
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		//on rempli la table si il est vide
		$rowsCP = $this->getTableObjet('categorie_document_profile')->select();
		if ($rowsCP->count() == 0) {
			$profilesResult = $this->getTableObjet('user_role')->select();
			foreach ($profilesResult as $profile) {
				if ($profile->role_id != "guest" && $profile->role_id != "user") {
					$cats = $this->getTableObjet('categorie_document')->select(array('deleted' => '0'));
					foreach ($cats as $cat) {
						$this->getTableObjet('categorie_document_profile')->insert(array('idCategorie' => $cat->id, 'idProfile' => $profile->role_id));
					}
				}
			}
		}

		$rows = $this->getTableCategorieDocs()->getCategoriesResident($all, $modeDp, $idFormulaire, $idProfile);

		return $rows;
	}

	private function loaddocumentsTab($loc, $idResa = 0, $edition = false, $idDp = 0, $params = array())
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$modedp = $idDp ? true : false;
		$idFormulaire = !empty($params['idFormulaire']) ? $params['idFormulaire'] : null;
		$fromSaveDocFicheResident = $params['fromSaveDoc'] ? $params['fromSaveDoc'] : false;

		$tools = new Tools();

		$dossier = getcwd().'/public/docs/locataires/'.$loc->id.'/uploads';
		$docs = $this->documentsDeRepertoire($dossier);

		$chemin = '/docs/locataires/'.$loc->id.'/uploads';
		$docsUploaded = $docs;
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=".$loc->id." edition=$edition idDp=$idDp");

		## catégorie documents
		$rows = $this->getTableObjet('categorie_document')->select();
		$categories = array();

		$docsCats = array();
		$cheminCats = array();

		// Si mode dp alors ne pas afficher certains champs
		// var_dump($rows->toArray());die();
		// $catToIgnore = array('Changement de chambre', 'Prolongation', 'Départ anticipé', );
		foreach ($rows as $cat) {
			$categories[] = $cat;
			//recuperation des documents par categorie
			if (is_dir(getcwd()."/public/docs/locataires/".$loc->id."/uploads/".$cat->id)) {
				$dir = getcwd()."/public/docs/locataires/".$loc->id."/uploads/".$cat->id;
				$docsCats[$cat->id] = $this->documentsDeRepertoire($dir);
				$cheminCats[$cat->id] = '/docs/locataires/'.$loc->id.'/uploads/'.$cat->id;
			}
		}
		//modeles de documents
		$tableModelesDocs = $this->getTableObjet('type_modeles_docs');
		$selectOdre = $tableModelesDocs->getSql()->select();
		$selectOdre->where(array('active' => 1, 'imprimableEnLot' => 1, 'ordre > 0'));
		$selectOdre->order(array('ordre ASC'));
		$typesOrdre = $tableModelesDocs->selectWith($selectOdre)->toArray();
		$selectNom = $tableModelesDocs->getSql()->select();
		$selectNom->where(array('active' => 1, 'imprimableEnLot' => 1, 'ordre IS NULL'));
		$selectNom->order(array('nom ASC'));
		$typesNom = $tableModelesDocs->selectWith($selectNom)->toArray();
		$rows = array_merge($typesOrdre, $typesNom);

		// $rows = $this->getTableObjet('type_modeles_docs')->select(array('active'=>1,'imprimableEnLot'=>1));

		$categoriesModel = array();

		$docsCatsModel = array();
		$cheminCatsModel = array();
		$modeles = array();

		//on affiche le modele reçu, si on a une rpestation calculé payé
		$prestaRegle = false;
		if ($idResa) {
			$pRows = $this->getPrestaTable()->getPrestationsDeResa($idResa, 'regle');
			if (!empty($pRows)) {
				$prestaRegle = true;
			}
		}

		foreach ($rows as $row) {
			$row = (object) $row;
			if ($row->code == 'RECU' && !$prestaRegle) {
				continue;
			}
			$categoriesModel[] = $row;
			$code = $row->code;
			if (is_dir(getcwd()."/public/docs/locataires/".$loc->id."/uploads/".$code)) {
				$dir = getcwd()."/public/docs/locataires/".$loc->id."/uploads/".$code;
				$docsCatsModel[$row->id] = $this->documentsDeRepertoire($dir);
				$cheminCatsModel[$row->id] = '/docs/locataires/'.$loc->id.'/uploads/'.$code;
			}
			$modeles[] = $row;
		}


		## Contrats signés
		## ~~~~~~~~~~~~~~~
		$contratsSignes	= array();
		$cheminContratsSignes = '';
		if (is_dir(getcwd()."/public/docs/locataires/".$loc->id."/uploads/contratsSignes")) {
			$dir = getcwd()."/public/docs/locataires/".$loc->id."/uploads/contratsSignes";
			$contratsSignes = $this->documentsDeRepertoire($dir);
			$cheminContratsSignes = '/docs/locataires/'.$loc->id.'/uploads/contratsSignes';
		}
		#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa contratsSignes=".json_encode($contratsSignes));

		// Dans le cas des contrats signés, ne pas afficher les originaux non signés
		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$contratsSignes1	= array();
		foreach ($contratsSignes as $filename) {
			if (preg_match("/_SIGNE_/", $filename)) {
				$contratsSignes1[]	= $filename;
			}
		}


		if ($edition) {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/editiondocuments')
				->setVariables(array(
					'modedp' => $modedp,
					'docs' => $docs,
					'dossier' => $chemin,
					'loc' => $loc,
					'categories' => $categories,
					'docsCats' => $docsCats,
					'cheminCats' => $cheminCats,
					'modeles' => $modeles,
					'categoriesModel' => $categoriesModel,
					'docsCatsModel' => $docsCatsModel,
					'cheminCatsModel' => $cheminCatsModel,
					'idResa' => $idResa,
					'contratsSignes' => ($contratsSignes1) ? $contratsSignes1 : $contratsSignes,
					'cheminContratsSignes' => $cheminContratsSignes,
					'idDp' => $idDp,
				));

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);
		} else {
			$editionData =  ['modeles' => $modeles,
			// a voir si utile
			'categoriesModel' => $categoriesModel,
			'docsCatsModel' => $docsCatsModel,
			'cheminCatsModel' => $cheminCatsModel,
		];
			$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();

			$currentResa = $this->getResaTable()->getResa($idResa);

			$modeCampCurrResa = $this->getCampagneTable()->getCampagneMode($currentResa->idCampagne);

			$showCertif = false;
			$parti = false;
			$resaParti = null;
			$resaAccueilli = null;
			$idLocataire = $loc->id;
			if($modeCampCurrResa && $modeCampCurrResa->afficherToutLesDocUsager == 2){
				$resasResult = $this->getResaTable()->getResaBy(array('id'=>$idResa));
			}else{
				$resasResult = $this->getResaTable()->getResaBy(array('idLocataire' => $idLocataire, /*'archive'=>'0',*/'notIn' => array('etat' => array(4, 12, 13, 14))));
			}
			
			$resas = array();

			$idLocataire = null;
			if ($idDp && $idDp > 0) {
				$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
				$idCampagne = $dp->idCampagne;
				$idLocataire = $dp->idLocataire;
			} else {
				foreach ($resasResult as $r) {
					//if(in_array($r->etat,array(4,12,13,14))) continue;
					//si on autorise tout les docs pr campagne on affiche tout, sinon on ignore les archivé
					//$modeCamp = $this->getCampagneTable()->getCampagneMode($r->idCampagne);
					$afficherToutLesDocUsager = ($modeCampCurrResa && $modeCampCurrResa->afficherToutLesDocUsager) ? $modeCampCurrResa->afficherToutLesDocUsager : 0;
					if((!$afficherToutLesDocUsager) && ($r->idNouvelleResa || $r->idAncienneResa) && $r->idCampagne == $currentResa->idCampagne){
						//si changement logement meme campagne : on affiche tout les docs de l'usager
						$afficherToutLesDocUsager = 1;
					}
					if(!$afficherToutLesDocUsager && $r->archive == '1') {
						continue;
					}
					
					$r->afficherToutLesDocUsager = $afficherToutLesDocUsager;
					$resa = $r;
					if ($r->etat == 6 && !$r->idNouvelleResa) {
						$parti = true;
						$resaParti = $r;
					}
					if ($r->etat == 7) {
						$showCertif = true;
						$resaAccueilli = $r;
					}
					$idCampagne = $r->idCampagne;
					$resas[] = $r;
				}
				$idLocataire = $resa->idLocataire;
			}

			$loc = $this->getLocataireTable()->getLocataire($idLocataire);

			$campagne = $this->getTableObjet('campagnes')->select(array('id' => $idCampagne))->current();
			$idTypeCampagne = $campagne->type;

			$modeCampagne = $this->getTableObjet('modes_campagne')->select(array('idCampagne' => $idCampagne))->current();


			$locale = 'fr_FR';
			$docs = $this->getDocumentTable()->getDocumentByCampagne($idCampagne, $locale);
			$langue = 0;

			$repertoire = getcwd().'/public/docs/locataires/'.$idLocataire.'/uploads';
			$autreDocs = $this->documentsDeRepertoire($repertoire);
			$folderAutre = '/docs/locataires/'.$idLocataire.'/uploads';


			## catégorie documents

			$categoriesResident = array();
			$documentsResidentParCat = array();

			$rows = $this->getCategoriesResident(true, $modedp, $idFormulaire);
			$categoriesResident = $rows;
			$categories = [];

			$docsCats = array();
			$cheminCats = array();
			$docsReservation = array();

			$labels = [
				't_doc_campagne' => html_entity_decode(utf8_encode($translator->translate('t_doc_campagne'))),
				't_doc_mailing' => html_entity_decode(utf8_encode($translator->translate('t_doc_mailing'))),
				't_doc_gestionnaire' => html_entity_decode(utf8_encode($translator->translate('t_doc_gestionnaire'))),
				't_doc_caf' => html_entity_decode(utf8_encode($translator->translate('t_doc_caf'))),
				];

			foreach ($rows as $key => $cat) {
				$cat->type = 'document';
				// $categories[$key] = $cat;
				//recuperation des documents par categorie
				if (is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$cat->id)) {
					$dir = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$cat->id;
					$docsCats[$cat->id] = $tools->lireDocumentsDeRepertoire($dir);
					$cheminCats[$cat->id] = '/docs/locataires/'.$idLocataire.'/uploads/'.$cat->id;
				}

				// si type EDL alors on on génére la liste des pdf par edl
				if (strtolower($cat->nom) == 'edl') {
					// var_dump('generer pf');die();
					// if(is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$cat->id)){
					// 	$dir = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$cat->id;
					// 	$docsCats[$cat->id] = $tools->lireDocumentsDeRepertoire($dir);
					// 	$cheminCats[$cat->id] = '/docs/locataires/'.$idLocataire.'/uploads/'.$cat->id;
					// }

					// récuperation des edls dispo
					$cat->edls = array();
					if (count($resas) > 0) {
						foreach ($resas as $resa) {
							// si la resa possede un edl

							$edls = $this->getTableObjet('edl')->select(array('id_reservations' => (int) $resa->id))->toArray();

							if (count($edls) > 0) {
								foreach ($edls as $key => $edl) {
									$edl['fileName'] = $this->generatePDFEDLAction($edl);
									$cat->edls[] = $edl;
								}
							}
						}
					}
				}

				$categories[] = $cat;
			}
			if (!$idDp) {
				if ($conf->mode == "HEC") {
					$row1 = $this->getTableObjet('type_modeles_docs')->select(array('id' => 6))->current();
					$row2 = $this->getTableObjet('type_modeles_docs')->select(array('id' => 7))->current();
					$row3 = $this->getTableObjet('type_modeles_docs')->select(array('id' => 11))->current();
					$rows = array($row1, $row2, $row3);
				} else {
					$rows = $this->getTableObjet('type_modeles_docs')->select(array('imprimableEnLot' => 1));
				}

				foreach ($rows as $row) {
					$row->type = 'modele';
					$categories[] = $row;
					$code = $row->code;

					// on force la valeur de l'id dans le tableau avec le code pour ne pas avoir le meme id que dans la table dynamique
					// $categories[][$code] = $row;
					if ($showCertif) {
						if ($code == "HEBER" || $code == "INFOL") {

							//$docsCats[$row->id] = "GENERER";
							$cheminCats[$row->code] = '/docs/locataires/'.$idLocataire.'/uploads/'.$code;
						} else {
							if (is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$code)) {
								$dir = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$code;
								$docsCats[$row->code] = $tools->lireDocumentsDeRepertoire($dir);
								$cheminCats[$row->code] = '/docs/locataires/'.$idLocataire.'/uploads/'.$code;
							}
						}
					}
					if ($parti) {
						if ($code == "DEPAR") {

							//$docsCats[$row->id] = "GENERER";
							$cheminCats[$row->id] = '/docs/locataires/'.$idLocataire.'/uploads/'.$code;
						}
					}

					if ($code == "ATTRE") {
						//$docsCats[$row->id] = "GENERER";
						$cheminCats[$row->id] = '/docs/locataires/'.$idLocataire.'/uploads/'.$code;
					}

					if ($code == "INFOL") {
						//$docsCats[$row->id] = "GENERER";
						$cheminCats[$row->id] = '/docs/locataires/'.$idLocataire.'/uploads/'.$code;
					}
				}

				//Mail enregistrer
				$repertoire = getcwd().'/public/docs/locataires/'.$idLocataire.'/mailing';
				$mailingDocs = $tools->lireDocumentsDeRepertoire($repertoire);
				$folderMailing = '/docs/locataires/'.$idLocataire.'/mailing';

				## documents demandes de resa
				//documents de base
				$folderLoc = "/docs/locataires/".$idLocataire;
				$champsBaseDoc = $this->getTableObjet('champs_formulaires')->select(array('idType' => 4, 'nature' => 'standard'));
				$idCategorieSejour = 0;
				$idCategorieDemande = 0;
				foreach ($categoriesResident as $cat) {
					if ($cat->parDefaut == 2) {
						$idCategorieSejour = $cat->id;
					}
					if ($cat->parDefaut == 3) {
						$idCategorieDemande = $cat->id;
					}
				}

				$resasDeLoc = array();
				$tableVD = $this->getTableObjet('valeurs_dynamiques');

				foreach ($resas as $resa) {
					$idCamp = $resa->idCampagne;
					$etatResa = $resa->etat;
					$resasDeLoc[$resa->id] = $resa;

					if ($resa->idAncienneResa && !$resa->afficherToutLesDocUsager) {
						$nr = $this->getResaTable()->getResa($resa->idAncienneResa);
						if ($nr) {
							$resa->dateArrivee = $nr->dateArrivee;
						}
					} elseif ($resa->idNouvelleResa && !$resa->afficherToutLesDocUsager) {
						continue;
					}

					$idResidence = null;
					if ($resa->idLogement) {
						$residenceLoge = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						if ($residenceLoge) {
							$resa->idResidence = $residenceLoge->idResidence;
						}
					}
					$documentsResidentParCat = $this->getDocumentTable()->getDocumentsResident($resa, $locale, $documentsResidentParCat);
					//print_r($documentsResidentParCat);exit();

					$table = $this->getTableObjet('champs_formulaires');
					$select = $table->getSql()->select();
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'), 'LEFT');
					$select->where(array('champs_formulaires.idType' => 4,
											'formulaires.idCampagne' => $resa->idCampagne,
											'champs_formulaires.nature' => 'standard',
											'champs_formulaires.active' => '1',
											));
					$champsBaseDoc = $table->selectWith($select);

					////////////////////////////////
					foreach ($champsBaseDoc as $row) {
						//if($resa->$champName){
						$champName = $row->equivalentSql;
						$champId = $row->id;
						$lmsgid = 'l_'.$champName.'_'.$champId;
						$libelle = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");
						$editable = $row->modifiableResident;
						$idChamp = $row->id;
						if (1) {
							$docArr = array('docName' => $resa->$champName ? $resa->$champName : '', 'libelle' => $libelle, 'editable' => $editable, 'idChamp' => $idChamp, 'resa' => $resa);
							$docObj = new Document();
							$docObj->libelle = $libelle;
							//$docObj->nom =$resa->$champName ? $resa->$champName : '';
							if ($resa->$champName) {
								$docObj->nom = $resa->$champName;
							} elseif ($loc->$champName) {
								$docObj->nom = $loc->$champName;
							} else {
								$docObj->nom = '';
							}
							$docObj->resa = $resa;
							$docObj->idChamp = $champId;
							$docObj->editable = $editable;
							$docObj->obligatoireSejour = $row->obligatoireSejour;
							if ($row->obligatoireSejour) {
								$docObj->idCategorie = $idCategorieSejour;
							} else {
								$docObj->idCategorie = $idCategorieDemande;
							}
							if ($resa->idNouvelleResa && !$resa->afficherToutLesDocUsager) {
								continue;
							}

							$documentsResidentParCat[$docObj->idCategorie][$resa->id][$docObj->idChamp] = $docObj;
						}
						//}
					}
					////////////////////////////
					//on recup les champs documents dynamiqeu par campagne

					$table = $this->getTableObjet('champs_formulaires');
					$select = $table->getSql()->select();
					//$select->join('valeurs_dynamiques', 'champs_formulaires.id = valeurs_dynamiques.idChamp',array('idValDyn'=>'id','valeur','idChamp','idReservation'),'LEFT');
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'), 'LEFT');
					$select->where(array('champs_formulaires.idType' => 4,
											'champs_formulaires.active' => '1',
											//'valeurs_dynamiques.idReservation'=>$resa->id,
											'formulaires.idCampagne' => $resa->idCampagne,
											'champs_formulaires.nature' => 'libre',
											'formulaires.active' => '1',
											));
					$rows = $table->selectWith($select);
					foreach ($rows as $row) {

						//if(($row->valeur && $row->idReservation == $resa->id) || !$row->idReservation){ //}
						if (1) {
							$valDyn = $tableVD->select(array('idReservation' => $resa->id, 'idChamp' => $row->id))->current();
							$lmsgid = 'l_'.$row->equivalentSql.'_'.$row->id;
							$libelle = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");
							if (1) {
								//$docArr = array('docName'=>$row->valeur ? $row->valeur : '','libelle'=>$libelle,'editable'=>$row->modifiableResident,'idChamp'=>$row->id,'resa'=>$resa);
								$docObj = new Document();
								$docObj->libelle = $libelle;
								$docObj->nom = ($valDyn->idReservation == $resa->id && $valDyn->valeur) ? $valDyn->valeur : '';
								if ($valDyn->idReservation == $resa->id) {
									$docObj->resa = $resa;
								}
								$docObj->idChamp = $row->id;
								$docObj->editable = $row->modifiableResident;
								$docObj->obligatoireSejour = $row->obligatoireSejour;

								if ($row->obligatoireSejour) {
									$docObj->idCategorie = $idCategorieSejour;
								} else {
									$docObj->idCategorie = $idCategorieDemande;
								}
								if ($resa->idNouvelleResa && !$resa->afficherToutLesDocUsager) {
									continue;
								}

								if (!is_array($documentsResidentParCat[$docObj->idCategorie]) || (!array_key_exists($docObj->idChamp, $documentsResidentParCat[$docObj->idCategorie]))) {
									$documentsResidentParCat[$docObj->idCategorie][$resa->id][$docObj->idChamp] = $docObj;
								} elseif ($valDyn->idReservation == $resa->id) {
									$documentsResidentParCat[$docObj->idCategorie][$resa->id][$docObj->idChamp] = $docObj;
								}
							}
						}
					}
				}


				# CAF
				$docsCAF = array();
				$repertoire = getcwd().'/public/docs/locataires/'.$idLocataire.'/caf';
				$docsCAF = $tools->lireDocumentsDeRepertoire($repertoire);

				$folderCAF = '/docs/locataires/'.$idLocataire.'/caf';

				##CAF APL
				$docsAPL = array();
				//$repertoire = getcwd().'/public/docs/locataires/'.$sess->loc->id.'/caf';
				$repertoire = getcwd().'/public/docs/caf';
				$docsCAFDeRep = $tools->lireDocumentsDeRepertoire($repertoire);
				$docsAPL = array();
				foreach ($docsCAFDeRep as $df) {
					$fn = pathinfo($df, PATHINFO_FILENAME);
					$ln = substr($fn, -2);
					if ($ln == 'EN' && $locale == "en_US") {
						$docsAPL[] = $df;
					} elseif ($ln == 'FR' && $locale == "fr_FR") {
						$docsAPL[] = $df;
					}
				}
				//$folderCAF = '/docs/locataires/'.$sess->loc->id.'/caf';
				$folderAPL = '/docs/caf';

				// Contrats signés
				// ~~~~~~~~~~~~~~~
				/*$dir			= getcwd()."/public/docs/locataires/".$idLocataire."/uploads/contratsSignes";
				$contratsSignes		= $tools->lireDocumentsDeRepertoire($dir);
				$cheminContratsSignes	= '/docs/locataires/'.$idLocataire.'/uploads/contratsSignes';
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : contratsSignes=".json_encode($contratsSignes));*/

				// Dans le cas des contrats signés, ne pas afficher les originaux non signés
				// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$contratsSignes1	= array();
				foreach ($contratsSignes as $filename) {
					if (preg_match("/_SIGNE_/", $filename)) {
						$contratsSignes1[]	= $filename;
					}
				}


				$resaDocs = array();
				foreach ($docsReservation as $key => $value) {
					$resaDocs[] = $value;
				}
			} elseif ($idDp) {
				$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
				$documentsResidentParCat = $this->getDocumentTable()->getDocumentsDp($dp, $locale);
				//print_r($documentsResidentParCat);exit();
			}

			//print_r($documentsResidentParCat);exit();

			$nbrDocsParCat = array();
			if ($idDp) {
				foreach ($documentsResidentParCat as $idCat => $ct) {
					$nbrDocsParCat[$idCat] = sizeof($ct);
				}
			} else {
				foreach ($documentsResidentParCat as $idCat => $ct) {
					$nbr = 0;
					if (!is_object($ct)) {
						foreach ($ct as $catDocs) {
							$nbr += sizeof($catDocs);
						}
					} else {
						$nbr = sizeof($ct);
					}
					$nbrDocsParCat[$idCat] = $nbr;
				}
			}
			## Date derinier upload ans une catégorie
			$dateDernierUploadParCat = array();
			foreach ($categoriesResident as $idCat => $cat) {
				$rowCat = $this->getDocumentTable()->getDateDernierUploadByCat($idCat, $idDp);
				if ($rowCat && $rowCat->dateCreation) {
					$dateDernierUploadParCat[$idCat] = date('d-m-Y', strtotime($rowCat->dateCreation));
				}
			}

			$logement = null;
			if ($resa->idLogement) {
				$logement = $this->getLogementTable()->getLogement($resa->idLogement);
			}

			$htmlViewPart = new ViewModel();
			// Nouvelle page document lié a la nouvelle fiche locataire
			if($conf->newFicheClientModal) {
				$pathTemplateViewPart = 'reservation/liste/documentsResident/newDocsResident';
				$pathTemplate = "reservation/liste/documentsNew";
			} else {
				$pathTemplateViewPart = 'reservation/liste/documentsresident';
				$pathTemplate = "reservation/liste/documents";
			}

			//print_r($documentsResidentParCat);exit();
			// No dev
			$htmlViewPart->setTerminal(true)
				->setTemplate($pathTemplateViewPart)
				->setVariables(array(
					'modedp' => $modedp,
					'documents' => $docs,
					'langue' => $langue,
					'labels' => $labels,
					'id' => $id,
					'showCertif' => $showCertif,
					'autreDocs' => $autreDocs,
					'folderAutre' => $folderAutre,
					'mailingDocs' => $mailingDocs,
					'folderMailing' => $folderMailing,
					'categories' => $categories,
					'docsCats' => $docsCats,
					'cheminCats' => $cheminCats,
					'contratsSignes' => ($contratsSignes1) ? $contratsSignes1 : $contratsSignes,
					'cheminContratsSignes' => $cheminContratsSignes,
					'docsReservation' => $resaDocs,
					'folderLoc' => $folderLoc,
					'docsCAF' => $docsCAF,
					'folderCAF' => $folderCAF,
					'docsAPL' => $docsAPL,
					'folderAPL' => $folderAPL,
					'loc' => $loc,
					'resa' => $resa,
					'parti' => $parti,
					'resaParti' => $resaParti,
					'resaAccueilli' => $resaAccueilli,
					'logement' => $logement,
					'idTypeCampagne' => $idTypeCampagne,
					'idDp' => $idDp,
					'idResa' => $idResa,
					'categoriesResident' => $categoriesResident,
					'documentsResidentParCat' => $documentsResidentParCat,
					'resasDeLoc' => $resasDeLoc,
					'locale' => $locale,
					'nbrDocsParCat' => $nbrDocsParCat,
					'idFormulaire' => $idFormulaire,
					'dateDernierUploadParCat' => $dateDernierUploadParCat,
					'modeCampagne' => $modeCampagne,
					'tools' => $tools,
					'conf' => $conf,
				));
			$editionData['categoriesResident'] = $categoriesResident;
			$htmlOutputRes = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

			if (json_encode(mb_convert_encoding($htmlOutputRes, 'UTF-8', 'UTF-8')) === false) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa htmlOutputResErr=".json_last_error_msg());
				$htmlOutputRes	= "<div>avec erreur dans json_encode dans htmlOutputRes ".__LINE__." ".json_last_error_msg()."</div>\n";
			}
			if($fromSaveDocFicheResident) {
				return $htmlOutputRes;
			} // on ne charge que la parties arborescence de doc pour la fiche resident aprés save de doc
			## modèles
			$modeles = $this->getTableObjet('type_modeles_docs')->select(array('active' => '1', 'imprimableEnLot' => '1'));
			$modeleDocs = array();
			foreach ($modeles as $c) {
				$modeleDocs[$c->id] = $c->nom;
			}

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate($pathTemplate)
				->setVariables(array(
					'editionData' => $editionData,
					'modedp' => $modedp,
					'docs' => $docsUploaded,
					'dossier' => $chemin,
					'loc' => $loc,
					'categories' => $this->getCategoriesResident(false, $modedp, $idFormulaire),
					'docsCats' => $docsCats,
					'cheminCats' => $cheminCats,
					'idResa' => $idResa,
					'contratsSignes' => ($contratsSignes1) ? $contratsSignes1 : $contratsSignes,
					'cheminContratsSignes' => $cheminContratsSignes,
					'htmlOP' => $htmlOutputRes,
					'idDp' => $idDp,
					'modeleDocs' => $modeleDocs,
					'conf' => $conf,
					'idFormulaire' => $idFormulaire,
				));

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);
		}

		if (json_encode(mb_convert_encoding($htmlOutput, 'UTF-8', 'UTF-8')) === false) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa htmlOutputErr=".json_last_error_msg());
			$htmlOutput	= "<div>avec erreur dans json_encode dans htmlOutput ".__LINE__." ".json_last_error_msg()."</div>\n";
		} else {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : lgHtmlOutput=".strlen($htmlOutput));
		}
		return $htmlOutput;
	}

	public function generatePDFEDLAction($edl)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getResaTable()->setAdapter($adapter);

		$resaId = $edl['id_reservations'];
		$locId = $edl['id_locataire'];
		$edlId = $edl['id'];
		$headerHtml = "";
		$footerHtml = "";
		$cats = array();

		## edl params
		$edlBaseParametres = $this->getEdlParametresTable()->fetchAll()->toArray();
		$headerHtml = $edlBaseParametres[0]['edl_modele_en_tete'];
		$footerHtml = $edlBaseParametres[0]['edl_modele_pied_de_page'];

		$locataire = $this->getLocatairesTable()->getLocataire($locId);

		$edl = $this->getEdlTable()->getById($edlId);
		$responsable = $this->getTableObjet('user')->select(array('user_id' => (int) $edl->user_id))->current();

		$observations_globales = $edl->observations_globales;

		$edl_modele = $this->getEdlModeleTable()->getRowByIdLogement($edl->id_logement);
		$msg_signature = $edl_modele ? $edl_modele->msg_signature : "";

		$typeofEdl = $edl->type;

		$dateEdl = $edl->date;

		$resa = $this->getResaTable()->getResaBy(array('id' => $resaId))->toArray();

		## cats
		$cats = $this->getEdlCatTable()->getByIdEdl($edlId)->toArray();
		foreach ($cats as $keyCat => $valueCat) {
			$catName = trim($valueCat['nom']);
			$catName = strtolower($catName);
			$catName = preg_replace('/\s+/', '', $catName);
			$catName = $this->remove_accents($catName);
			$catName = str_replace(array('\'', '"'), '', $catName);

			// get all sous cats
			$sousCats = $this->getEdlSousCatTable()->getByIdEdlCat($valueCat['id'])->toArray();
			$cats[$keyCat]['sousCats'] = $sousCats;
			foreach ($sousCats as $keySousCat => $valueSousCat) {
				$sousCatName = trim($valueSousCat['nom']);
				$sousCatName = strtolower($sousCatName);
				$sousCatName = preg_replace('/\s+/', '', $sousCatName);
				$sousCatName = $this->remove_accents($sousCatName);
				$sousCatName = str_replace(array('\'', '"'), '', $sousCatName);

				// get articles
				$articlesArr = $this->getEdlArticleTable()->getByIdEdlSousCat($valueSousCat['id'])->toArray();
				$articles = array();

				//on y ajoute les 3 images si existent
				foreach ($articlesArr as $art) {
					for ($i = 0; $i <= 2; $i++) {
						$articleName = trim($art['nom']);
						$articleName = strtolower($articleName);
						$articleName = preg_replace('/\s+/', '', $articleName);
						$articleName = $this->remove_accents($articleName);
						$articleName = str_replace(array('\'', '"'), '', $articleName);

						$fileName = "picture-".$catName."-".$sousCatName."-".$articleName;
						$fileName .= '-'.$i.'.jpg';

						if (file_exists($folder.'/'.$fileName)) {
							$art['image'.$i] = $url.$fileName;
						} else {
							$art['image'.$i] = "";
						}
					}

					$art['vetuste'] = $vetuste;
					$art['pictures'] = [];
					$articles[] = $art;
				}
				$cats[$keyCat]['sousCats'][$keySousCat]['articles'] = $articles;
			}
		}
		//fin cats


		if (count($resa) > 0) {
			$logement = $this->getLogementTable()->getLogement($resa[0]['idLogement']);
			$batiment = $this->getBatimentTable()->getBatiment($logement->idBatiment);
			$residence = $this->getResidencesTable()->getResidence($batiment->idResidence);
			$locataire->batiment = $residence->nom;
			$locataire->residence = $batiment->nom;
			$locataire->dateArrivee = $resa[0]['dateArrivee'];
			$locataire->dateDepart = $resa[0]['dateDepart'];
			$locataire->numeroChambre = $resa[0]['numeroChambre'];

			$locataire->dateNaissance = date('d/m/Y', strtotime($locataire->dateNaissance));
			// $locataire->civilite = $loc->langue == "UK" ? $resa[0]['civiliteEn'] : $resa[0]['civilite'];
			// var_dump($locataire);die();
		}

		$headerFieds = $this->getfields($headerHtml);
		foreach ($headerFieds as $row) {
			$valeur = $locataire->$row;
			$valeur = nl2br($valeur);
			$headerHtml = str_replace("%".$row."%", $valeur, $headerHtml);
		}

		$footerFields = $this->getfields($footerHtml);
		foreach ($footerFields as $row) {
			$valeur = $locataire->$row;
			$valeur = nl2br($valeur);
			$footerHtml = str_replace("%".$row."%", $valeur, $footerHtml);
		}


		$pdf = new \TCPDF("P", "px", "A4", true, 'UTF-8', false);
		// $pdf = new Mytcpdf("P", "px", "A4", true, 'UTF-8', false);
		$pdf->SetFooterMargin(30);
		$pdf->SetFooterData('', 0, '', '<b>FOOTER TEST</b>');
		$pdf->setPrintFooter(false);
		$pdf->setPrintHeader(true);

		// $pdf->setFooterData('', 0,'' , $footerHtml);
		//$pdf->SetFont('times');
		// $pdf->SetFont('helvetica', 'B', 20);

		$pdf->SetAutoPageBreak(true, 10);
		$pdf->SetTopMargin(6);

		$pdf->AddPage();

		$pdf->SetRightMargin(0);
		$pdf->SetLeftMargin(0);

		// set JPEG quality

		// check if logo exist
		if (file_exists(getcwd().'/public/img/logo.png')) {
			$pdf->setJPEGQuality(75);
			$logo = file_get_contents(getcwd().'/public/img/logo.png');
			$pdf->Image('@'.$logo, 20, 10, 100, 'PNG', '', '', '');
		}

		$pdf->ln(10);
		$pdf->writeHTMLCell(300, '', $pdf->getX() + 270, '', '<div>'.$headerHtml.'</div>', 0, 50, 0, true, 'T', false);

		$pdf->ln(10);
		$htmlTypeEdl = "<p>Etat des lieux: ".$typeofEdl.". Effectué le ".date('d/m/Y', strtotime($dateEdl)).".</p>";
		$pdf->writeHTMLCell(0, '', $pdf->getX() + 10, '', '<div>'.$htmlTypeEdl.'</div>', 0, 1, 0, true, 'T', false);
		$pdf->ln(10);

		$styleHtml = '<style>ol { list-style-type: none; } div.catContainer { border: 1px solid #212121; }</style>';
		// $htmlBody = $styleHtml.'<div>';

		foreach ($cats as $keyCat => $cat) {
			$htmlBody = '';
			$catName = $edlBaseParametres[0]['afficher_label_cat'] ? $cat['nom'] : '';
			$htmlBody .= $styleHtml.'<div class="catContainer"><b class="catName">'.$catName.'</b>';
			$htmlBody .= '<ol class="ul-cat">';

			foreach ($cat['sousCats'] as $keySousCat => $sousCat) {
				$sousCatName = $edlBaseParametres[0]['afficher_label_sous_cat'] ? $sousCat['nom'] : '';
				$htmlBody .= '<div><b>'.$sousCatName.'</b>';
				$htmlBody .= '<div class="ul-sousCat">';

				foreach ($sousCat['articles'] as $keyArticle => $article) {
					if ($edlBaseParametres[0]['afficher_input_nombres'] != '') {
						$htmlBody .= '<div style="page-break-inside:avoid;">&nbsp;&nbsp;<span style="font-weight: 100; color: #212121; text-decoration: underline;">'.trim($article['nom']).'</span> <br>&nbsp;&nbsp;&nbsp;Nombre: '.intval($article['nombre']);
					}

					if (isset($article['etat']) && !empty($article['etat']) && $edlBaseParametres[0]['afficher_button_vetuste'] != '') {
						$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Vetusté: '.$article['etat'];
					}

					if ($edlBaseParametres[0]['afficher_label_replacement_cost'] != '') {
						if (isset($article['cout']) && !empty($article['cout'])) {
							if ($article['type'] == 'mobilier') {
								$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Coût de remplacement: '.$article['cout'].'€';
							} elseif ($article['type'] == 'immobilier') {
								$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Coût de remplacement par m²: '.$article['cout'].'€';
							}
						} else {
							if ($article['type'] == 'mobilier') {
								$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Coût de remplacement : 0 €';
							} elseif ($article['type'] == 'immobilier') {
								$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Coût de remplacement par m² : 0 €';
							}
						}
					}

					if (isset($article['commentaire']) && !empty($article['commentaire']) && $edlBaseParametres[0]['afficher_input_remarques'] != '') {
						$htmlBody .= '<br>&nbsp;&nbsp;&nbsp;Commentaire: '.$article['commentaire'];
					}

					if ($edlBaseParametres[0]['afficher_input_photos'] != '') {
						if ($article['image0'] != "" || $article['image1'] != "" || $article['image2'] != "") {
							$htmlBody .= '<br>';
							if ($article['image0'] != "" && file_exists(getcwd().'/public'.$article['image0'])) {
								$htmlBody .= '&nbsp;&nbsp;&nbsp;<img src="'.getcwd().'/public'.$article['image0'].'" width="75" height="75" border="0" />';
							}
							if ($article['image1'] != "" && file_exists(getcwd().'/public'.$article['image1'])) {
								$htmlBody .= '&nbsp;&nbsp;&nbsp;<img src="'.getcwd().'/public'.$article['image1'].'" width="75" height="75" border="0" />';
							}
							if ($article['image2'] != "" && file_exists(getcwd().'/public'.$article['image2'])) {
								$htmlBody .= '&nbsp;&nbsp;&nbsp;<img src="'.getcwd().'/public'.$article['image2'].'" width="75" height="75" border="0" />';
							}
						}
					}

					$htmlBody .= '</div>';
				}

				$htmlBody .= '</div>';
				$htmlBody .= '</div>';
			}

			$htmlBody .= '</ol>';
			$htmlBody .= '</div>';
			// $pdf->writeHTML($htmlBody, false, false, true, false, '');
			$pdf->writeHTMLCell(550, '', $pdf->getX() + 15, '', '<div>'.$htmlBody.'</div>', 0, 50, 0, true, '', false);
		}

		// $htmlBody .= '</div>';

		// $pdf->writeHTML($htmlBody, false, false, true, false, '');

		if (isset($observations_globales) && !empty($observations_globales)) {
			$html = '<div style="page-break-inside:avoid;"><b>Observations globales: </b><p>'.$observations_globales.'</p></div>';
			$pdf->ln(10);
			$pdf->writeHTMLCell(550, '', $pdf->getX() + 20, '', '<div>'.$html.'</div>', 1, 100, 0, true, 'T', false);
		}

		// Ajout des prestations
		$prestations = $this->getEdlPrestationsTable()->getByEdlId($edlId)->toArray();
		if (count($prestations) > 0) {
			$pdf->ln(10);
			// $htmlPrestations = "<table nobr='true'>
			$htmlPrestations = "<table nobr='true'>
				<thead>
					<tr>
						<th><b>Libellé</b></th>
						<th><b>Qtés</b></th>
						<th><b>Montant unitaire</b></th>
						<th><b>Montant total</b></th>
						<th><b>Commentaires</b></th>
					</tr>
				</thead>
				<tbody>";

			$totalPresta = 0;
			foreach ($prestations as $key => $prestation) {
				$totalPresta += $prestation['montant_unitaire'];

				$htmlPrestations .= '<tr>
					<td>'.$prestation['libelle'].$prestation['libelle_ajouter'].'</td>
					<td style="text-align:left">'.$prestation['quantite'].'</td>
					<td style="text-align:center">'.number_format((float)$prestation['montant_unitaire'], 2, '.', '').'€</td>
					<td style="text-align:center">'.number_format((float)$prestation['montant_total'], 2, '.', '').'€</td>
					<td style="text-align:center">'.$prestation['commentaires'].'</td>
				</tr>';
			}

			$htmlPrestations .= "<tr><td></td><td></td><td></td><td></td><td><b>TOTAL</b></td></tr>";
			$htmlPrestations .= "<tr><td></td><td></td><td></td><td></td><td>".number_format((float)$totalPresta, 2, '.', '')."€</td></tr></tbody></table>";
			$pdf->writeHTMLCell(0, '', $pdf->getX() + 20, '', '<div><b>PRESTATIONS</b><br>'.$htmlPrestations.'</div>', 0, 350, 0, true, 'T', false);
		}

		$edlDir = getcwd().'/public/docs/locataires/'.$locataire->id.'/edl-'.$edlId;

		if (file_exists($edlDir.'/signature-responsable.png') && file_exists($edlDir.'/signature-locataire.png')) {
			$pdf->ln(10);

			$pdf->writeHTMLCell(167, '', $pdf->getX() + 250, $pdf->getY(), '<div><p>Responsable: '.$responsable->display_name.'</p></div>', 0, 0, 0, true, 'J', true);
			$pdf->writeHTMLCell(200, '', $pdf->getX() - 10, '', '<div><p>Locataire: '.$locataire->nom.' '.$locataire->prenom.'</p></div>', 0, 1, 0, true, 'J', true);

			$signatureResponsable = file_get_contents($edlDir.'/signature-responsable.png');
			$pdf->Image('@'.$signatureResponsable, 180, '', 200, 50, 'PNG', '', '', true, 150, '', false, false, 0, false, false, false);

			$signatureLocataire = file_get_contents($edlDir.'/signature-locataire.png');
			$pdf->Image('@'.$signatureLocataire, 325, '', 200, 50, 'PNG', '', '', true, 150, '', false, false, 0, false, false, false);
			$pdf->ln(100);
		}

		$pdf->writeHTMLCell(0, '', $pdf->getX() + 250, $pdf->getY(), '<div><p>Fait le: '.date('d/m/Y', strtotime($dateEdl)).'</p></div>', 0, 0, 0, true, 'J', true);

		$pdf->writeHTMLCell(540, '', $pdf->getX() + 20, '', '<div style="page-break-inside:avoid;"><p>'.$msg_signature.'</p></div>', 0, 50, 0, true, 'T', false);
		if (isset($footerHtml) && !empty($footerHtml)) {
			$pdf->SetY(-5);
			// $pdf->Cell(0, 3, 'Page '.$pdf->getAliasNumPage().'/'.$pdf->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
			// $pdf->ln(50);
			$pdf->writeHTMLCell(0, '', $pdf->getX() + 20, '', '<div>'.$footerHtml.'</div>', 0, 0, 0, true, 'T', false);
		}

		$pdf->lastPage();

		// $pdf->deletePage($pdf->getPage());
		// $pdf->ln(10);

		// $pdf->writeHTMLCell(0, '', $pdf->getX() + 20, '', '<div>'.$footerHtml.'</div>', 0, 350, 0, true, 'T', false);

		// $pdf->ln(50);
		// $tampon = file_get_contents('https://www.awelty.fr/medias/images/tampon.png');
		// $pdf->Image('@'.$tampon, 300, '', 100, '',  'PNG', '', '', false);

		if (is_dir($edlDir)) {
			$pdf->Output($edlDir."/edl.pdf", 'F');
		} else {
			if (mkdir($edlDir, 0777, true)) {
				$pdf->Output($edlDir."/edl.pdf", 'F');
			}
		}

		$fileName = "/docs/locataires/".$locataire->id."/edl-".$edlId."/edl.pdf";
		return $fileName;
	}

	private function remove_accents($string)
	{
		if (!preg_match('/[\x80-\xff]/', $string)) {
			return $string;
		}

		$chars = array(
			// Decompositions for Latin-1 Supplement
			chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
			chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
			chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
			chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
			chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
			chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
			chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
			chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
			chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
			chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
			chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
			chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
			chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
			chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
			chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
			chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
			chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
			chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
			chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
			chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
			chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
			chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
			chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
			chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
			chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
			chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
			chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
			chr(195).chr(191) => 'y',
			// Decompositions for Latin Extended-A
			chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
			chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
			chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
			chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
			chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
			chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
			chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
			chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
			chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
			chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
			chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
			chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
			chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
			chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
			chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
			chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
			chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
			chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
			chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
			chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
			chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
			chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
			chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
			chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
			chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
			chr(196).chr(178) => 'IJ', chr(196).chr(179) => 'ij',
			chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
			chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
			chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
			chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
			chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
			chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
			chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
			chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
			chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
			chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
			chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
			chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
			chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
			chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
			chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
			chr(197).chr(146) => 'OE', chr(197).chr(147) => 'oe',
			chr(197).chr(148) => 'R', chr(197).chr(149) => 'r',
			chr(197).chr(150) => 'R', chr(197).chr(151) => 'r',
			chr(197).chr(152) => 'R', chr(197).chr(153) => 'r',
			chr(197).chr(154) => 'S', chr(197).chr(155) => 's',
			chr(197).chr(156) => 'S', chr(197).chr(157) => 's',
			chr(197).chr(158) => 'S', chr(197).chr(159) => 's',
			chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
			chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
			chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
			chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
			chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
			chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
			chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
			chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
			chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
			chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
			chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
			chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
			chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
			chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
			chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
			chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
		);

		$string = strtr($string, $chars);
		return $string;
	}

	public function uploadfichedocumentAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// print_r($_FILES);
			$error = "";

			$idLocataire = (int) $this->params()->fromRoute('id', 0);
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire);

			$tool = new Tools();

			$idCategorie = $request->getPost('idCategorie');
			$nomCategorie = $request->getPost('nomCategorie');
			$idResa = $request->getPost('idResa', 0);
			$idDp = $request->getPost('idDp', 0);

			if (!is_dir(getcwd()."/public/docs/locataires")) {
				mkdir(getcwd()."/public/docs/locataires");
			}

			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads")) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads");
			}
			$folder = "./public/docs/locataires/".$idLocataire."/uploads";

			$table = $this->getTableObjet('categorie_document');
			/**if ($idCategorie == '-1') {
				//nouvelle categorie

				if ($nomCategorie != "") {
					//on vérifie si la catégorie existe déjà pour eviter de creer plusieurs fois la meme categorie
					$cat = $table->select(array('nom'=>$nomCategorie))->current();
					if (!$cat) {
						$table->insert(array('nom'=>$nomCategorie));
						$idCategorie = $table->lastInsertValue;
					} else {
						$idCategorie = $cat->id;
					}
				} else {
					$error = "Veuillez fournir un nom de categorie";
				}
			}*/

			if ($idCategorie > 0) {
				if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie)) {
					mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie);
				}
				$folder = "./public/docs/locataires/".$idLocataire."/uploads/".$idCategorie;

				//on mis à jour le nom de la categorie si modifier
				$cat = $table->select(array('id' => $idCategorie))->current();
				if($cat->idParent > 0) {
					$arrNom = explode('-', $nomCategorie);
					$nomCategorie = end($arrNom);
				}
				//if($cat->nom != $nomCategorie){
				///if ($nomCategorie != "") {
				///$table->update(array('nom'=>$nomCategorie), array('id'=>$idCategorie));
				///}
				//}
			}
			// function processFile()

			$passer = 0;//0:pas fourni , 1:pas chargé, 2:extension non valide, 3:uploader
			$namePJ = "";
			$originalName = isset($_FILES['document']['name']) ? $_FILES['document']['name'] : '';
			if ($idCategorie) {
				if (isset($_FILES['document']) && $_FILES['document']['error'] == 0 && $error == "") {
					$passer = 1;

					$extension = pathinfo($_FILES['document']['name'], PATHINFO_EXTENSION);
					$filename = pathinfo($_FILES['document']['name'], PATHINFO_FILENAME);
					$originalName = $_FILES['document']['name'];

					$lastId = $this->getDocumentTable()->getLastId();
					$fileDocId = 1;
					if ($lastId) {
						$fileDocId = (int) $lastId->id + 1;
					}

					$namePJ = $this->removeAccent($filename)."_".date('Y-m-d-his')."_".$fileDocId.".".$extension;

					$allowed = explode(',', $this->getConfig()->extension);
					$mimeType	= mime_content_type($_FILES['document']['tmp_name']);

					if (!in_array(strtolower($extension), $allowed)) {
						$passer = 2;
					} elseif($mimeType != $tool->getMimeType(strtolower($extension))) {
						//controle mimeType
						$passer = 6;
					} else {

						//unlink($folder.'/'.$conf->logo);

						if (move_uploaded_file($_FILES['document']['tmp_name'], $folder.'/'.$namePJ)) {
							//upload réussi

							$passer = 3;
						}
					}
				}
			} else {
				$passer = 4;
			}

			//$htmlOutput = $this->loaddocumentsTab($loc, $idResa, false, $idDp);

			$msg = "";
			switch ($passer) {
				case 0: $msg = "<span class='error red'>Erreur upload 1</span>";
					break;
				case 1: $msg = "<span class='error red'>Erreur upload 2</span>";
					break;
				case 2: $msg = "<span class='error red'>Erreur extension(seulement pdf autorisé)</span>";
					break;
				case 3: $msg = "<span class='success green'>Fichier uploader</span>";
					break;
				case 4: $msg = "<span class='error red'>Veuillez choisir une catégorie</span>";
					break;
				case 6: $msg = "<span class='error red'>Erreur MIME TYPE erroné</span>";
					break;
			}


			$view = new JsonModel(array(
						'success' => true,
						'passer' => $passer,
						'msg' => $msg,
						'pjname' => $namePJ,
						'htmlOP' => $htmlOutput,
						'erreur' => $error,
						'originalName' => $originalName,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	##Sauvegarder le document depuis la fiche locataire - onglet documents
	public function saveDocumentResidentAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idCategorie = $request->getPost('idCategorie', 0);
			$docName = $request->getPost('docName', null);
			$etatResa = $request->getPost('etatResa', array());
			$libelle = $request->getPost('libelle', 0);
			$idModele = $request->getPost('idModele', null);
			$typeDoc = $request->getPost('typeDoc', null);
			$idResa = $request->getPost('idResa', null);
			$idDp = $request->getPost('idDp', null);
			$idLocataire = $request->getPost('idLocataire', 0);
			$idFormulaire  = $request->getPost('idFormulaire', 0);
			$withHtml = $request->getPost('withHtml', true);

			$error = "";
			if (!$idCategorie) {
				$error = "Veuillez choisir une catégorie<br>";
			}
			if (!$docName && $typeDoc == "statique") {
				$error .= "Veuillez uploader le document<br>";
			}
			if (!$libelle) {
				$error .= "Veuillez remplir le libellé<br>";
			}
			if (!$idResa && !$idDp) {
				$error .= "idReservation Vide<br>";
			}

			if ($error != "") {
				$view = new JsonModel(array(
						'success' => false,
						'msg' => $error,
				));
				$view->setTerminal(true);
				return $view;
			}
			if ($typeDoc == 'statique') {
				$idModele = null;
			}

			## fusion demande en cours avec validé
			if(!empty($etatResa) && in_array(1,$etatResa)){
				array_push($etatResa,10);
			}

			//on save le doc
			$doc = new Document();
			$doc->idCategorie = $idCategorie;
			$doc->nom = $docName;
			$doc->doc64 = "";
			if (!$libelle) {
				$libelle = $doc->nom;
			}
			$doc->libelle = $libelle;
			$doc->etatResa = $etatResa;
			$doc->isResident = 1;
			$doc->typeDoc = $typeDoc;
			$doc->idModele = $idModele;
			$doc->idUser = $gestId;

			$docId = $this->getDocumentTable()->saveDocument($doc);
			if ($idResa) {
				$docResa = $this->getTableObjet('document_locataire')->select(array('idDocument' => $docId, 'idReservation' => $idResa))->current();
				if (!$docResa) {
					$this->getTableObjet('document_locataire')->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
				}
			} elseif ($idDp) {
				$docDp = $this->getTableObjet('document_dp')->select(array('idDocument' => $docId, 'idDp' => $idDp))->current();
				if (!$docDp) {
					$this->getTableObjet('document_dp')->insert(array('idDocument' => $docId, 'idDp' => $idDp));
				}
			}
			$loc = $this->getLocataireTable()->getLocataire($idLocataire);
			if ($withHtml !== 'false') {
				$htmlOutput = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp, array('idFormulaire' => $idFormulaire, ['fromSaveDoc' => true])), 'UTF-8', 'UTF-8');
			} else {
				$htmlOutput = "";
			}

			$view = new JsonModel(array(
						'success' => true,
						'msg' => ('Document sauvegardé'),
						'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Enregistrement ordre documents(fiche usager-onglet Documents)
	public function saveOrdreDocumentsAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$idLoc = $request->getPost('idLoc', null);
			$idDp = $request->getPost('idDp', null);
			$idResa = $request->getPost('idResa', null);
			$idFormulaire = $request->getPost('idFormulaire', null);
			if (!empty($ids)) {
				foreach ($ids as $row) {
					$idDoc = $row['idDoc'];
					$ordre = $row['ordre'];
					$this->getDocumentTable()->saveOrdre($idDoc, $ordre);
				}
			}

			$loc = $this->getLocataireTable()->getLocataire($idLoc);
			$htmlOutput = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp, array('idFormulaire' => $idFormulaire)), 'UTF-8', 'UTF-8');

			$view = new JsonModel(array(
							'success' => true,
							'htmlOP' => $htmlOutput,
				));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## envois documents coché dans l'onglet documents en PJ
	public function envoyerMailDocsAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$session = new Container('mailing');
		$session->mailOptions = null;

		if ($request->isXmlHttpRequest()) {
			$idsDocs = $request->getPost('ids', array());
			$idLoc = $request->getPost('idLoc', null);
			//$idDp = $request->getPost('idDp', null);
			$idResa = $request->getPost('idResa', null);
			$liensPJ = $request->getPost('liensPJ', null);
			$success = false;
			$msg = '';
			$idModele = '';

			if (!empty($liensPJ) && $idResa > 0) {
				//on vérifie si on a le modèle de type Documents en pièces jointes configuré
				$modeles = $this->getModelesMailTable()->getModelesByCode('docs_en_pj');
				if($modeles->count() > 0) {
					$modele = $modeles->current();
					$idTypeModele = $modele->idType;
					$liens = array();
					foreach ($liensPJ as $row) {
						$idDoc = $row['idDoc'];
						$lien = $row['lien'];
						$liens[] = $lien;
					}
					$idModele = $modele->id;

					try {
						## Les paramètres de envoyerMail sont envoyés au controlleur ReservationController.php
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$options = array('liensDocsPJ' => $liens, 'idResa' => $idResa, 'idModele' => $idModele);
						$session->mailOptions = $options;

						/*$this->forward()->dispatch('Application\Controller\Reservation', array('action' => 'envoyerMail', 'mesParams' => array('idResa' => $idResa, 'typeEmail' => $idTypeModele, 'options'=> $options)));
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa typeEmail=$typeEmail apres");


						*/
						$msg = "Chargement de modèle mailing";
						$success = true;

					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Appel du controlleur de réservation : ERROR-exception=".$ex->getMessage());
						$msg = $ex->getMessage();
					}

				} else {
					$msg = "Aucun modèle mail de type Documents en pièces jointes configuré";
				}

			} else {
				if(!$idResa) {
					$msg = "idResa vide";
				} else {
					$msg = "Aucun document à joindre trouvé";
				}
			}

			$view = new JsonModel(array(
							'success'	=> $success,
							'msg'		=> $msg,
							'idModele'	=> $idModele,
				));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function deletedocumentAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$lien = $request->getPost('lien');
			if ($lien) {
				$this->deleteFile(getcwd().'/public'.$lien);
			}

			$idDoc = $request->getPost('idDoc', null);
			$idLoc = $request->getPost('idLoc', null);
			$idDp = $request->getPost('idDp', null);
			$idResa = $request->getPost('idResa', null);
			$idFormulaire = $request->getPost('idFormulaire', null);
			$htmlOutput = "";
			if ($idDoc) {
				if ($idResa) {
					$this->getTableObjet('document_locataire')->delete(array('idReservation' => $idResa, 'idDocument' => $idDoc));
				}
				if ($idDp) {
					$this->getTableObjet('document_dp')->delete(array('idDp' => $idDp, 'idDocument' => $idDoc));
				}
				$this->getDocumentTable()->deleteDocument($idDoc);
				$loc = $this->getLocataireTable()->getLocataire($idLoc);
				$htmlOutput = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp, array('idFormulaire' => $idFormulaire)), 'UTF-8', 'UTF-8');
			}

			$view = new JsonModel(array(
						'success' => true,
						'msg' => ('Document supprimé'),
						'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
	}


	private function documentsDeRepertoire($dir)
	{
		$docs = array();
		if (is_dir($dir)) {
			if ($dh = opendir($dir)) {
				while (($file = readdir($dh)) !== false) {
					if (!is_dir($dir.$file)) {
						$ext = pathinfo($file, PATHINFO_EXTENSION);
						if ($ext) {
							$docs[] = $file;
						}
					}
				}
			}
		}
		return $docs;
	}

	############MODELES DE DOCUMENTS###############

	//Impression groupe
	public function impressiongroupeAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : POST=".json_encode($_POST));
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$mode = $request->getPost('mode', '');
			$from = $request->getPost('from', '');
			$ids = $request->getPost('ids', array());
			$idResa = $request->getPost('idResa', 0);
			$idDp = $request->getPost('idDp', 0);
			$idsCampagnes = $request->getPost('idsCampagnes', array());
			$idsEtatResa = $request->getPost('idsEtatResa', array());
			$idsResidences = $request->getPost('idsResidences', array());

			$where = array('active' => 1, 'imprimableEnLot' => 1);
			$tableModeleDoc = $this->getTableObjet('type_modeles_docs');
			if ($mode == 'suivis') {
				//$where['typeModele'] = 'suivis';
				if (!empty($idsCampagnes)) {
					$idsCampagnes = array_unique($idsCampagnes);
					$select	= $tableModeleDoc->getSql()->select();
					$select->join('campagnes_modeles_doc', 'campagnes_modeles_doc.idModele = type_modeles_docs.id', array('idModeleCampagne' => 'id', 'idModele'));
					$select->where(array('type_modeles_docs.active' => '1', 'type_modeles_docs.imprimableEnLot' => '1', 'type_modeles_docs.typeModele' => 'suivis'));
					$select->where->in('campagnes_modeles_doc.idCampagne', $idsCampagnes);
					$modeles = $tableModeleDoc->selectWith($select);
				} else {
					$modeles = $this->getTableObjet('type_modeles_docs')->select($where);
				}
			} else {
				$where['typeModele'] = 'reservation';
				if (!empty($idsCampagnes) || !empty($idsResidences)) {
					$idsCampagnes = array_unique($idsCampagnes);

					$select	= $tableModeleDoc->getSql()->select();
					$select->join('documents', 'type_modeles_docs.id = documents.idModele', array('idMDoc' => 'id'), 'LEFT');
					if (!empty($idsCampagnes)) {
						$select->join('document_campagne', 'document_campagne.idDocument = documents.id');
						$select->where->in('document_campagne.idCampagne', $idsCampagnes);
					}
					if (!empty($idsResidences)) {
						$select->join('document_residence', 'document_residence.idDocument = documents.id');
						$select->where->in('document_residence.idResidence', $idsResidences);
					}
					$select->where(array('documents.deleted' => '0',
										'documents.isResident' => '1',
										'type_modeles_docs.imprimableEnLot' => 1,
										'type_modeles_docs.active' => 1,
										//'type_modeles_docs.typeModele'=>'reservation',
										));

					if (!empty($idsEtatResa)) {
						$idsEtatResa = array_unique($idsEtatResa);
						$sqlWhere = '(';
						foreach ($idsEtatResa as $idEtatResa) {
							$sqlWhere .= "(documents.etatResa LIKE '%$idEtatResa%') OR ";
						}
						$sqlWhere = substr($sqlWhere, 0, -4).')';//on enleve le dernier OR
						$select->where($sqlWhere);
					}
					$resultSet = $tableModeleDoc->selectWith($select);
					$modeles = array();
					foreach ($resultSet as $r) {
						$modeles[$r->id] = $r;
					}
				} else {
					$modeles = $this->getTableObjet('type_modeles_docs')->select($where);
				}
			}

			$idCampagne = '';
			if ($from == 'suivisTab') {
				if ($idDp) {
					$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
					$idCampagne = $dp ? $dp->idCampagne : null;
				} elseif ($idResa) {
					$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
					$idCampagne = $resa ? $resa->idCampagne : null;
				}
				if ($idCampagne) {
					$tableModeleDoc = $this->getTableObjet('type_modeles_docs');
					$select	= $tableModeleDoc->getSql()->select();
					$select->join('campagnes_modeles_doc', 'campagnes_modeles_doc.idModele = type_modeles_docs.id', array('idModeleCampagne' => 'id', 'idModele'));
					$select->where(array('campagnes_modeles_doc.idCampagne' => $idCampagne, 'type_modeles_docs.active' => '1', 'type_modeles_docs.imprimableEnLot' => '1', 'type_modeles_docs.typeModele' => 'suivis'));
					$modeles = $tableModeleDoc->selectWith($select);
				}
			}
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/impressiongroupe')
				->setVariables(array(
					'modeles' => $modeles,
					'idResa' => $idResa,
					'mode' => $mode,
					'from' => $from,
					'ids' => $ids,
					'idCampagne' => $idCampagne,
				));

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function validerimpressionAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idModele = $request->getPost('idModele');
			$idCampagne = $request->getPost('idCampagne', 0);
			$mode = $request->getPost('mode', '');
			$idsResa = $request->getPost('ids');//par forcement idsResa, mais idsDp si le mode==dp
			$idsResa = array_unique($idsResa);
			$idsMembresMenage = $request->getPost('idsMembresMenage', array());
			//print_r($idsResa);exit();
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idsResa=".json_encode($idsResa));

			$urlGeneratedFile = $this->genererPdfMergeDocument($idsResa, $idModele, $mode, array('idCampagneModeleDoc' => $idCampagne, 'idsMembresMenage' => $idsMembresMenage));

			$view = new JsonModel(array(
				'success' => true,
				'urlGeneratedFile' => $urlGeneratedFile,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	private function genererPdfMergeDocument($idsResa, $idModele, $mode = "", $params = array())
	{
		##PDF MERGING
		include(getcwd().'/externalibs/PDFMerger/PDFMerger.php');

		$pdf = new \PDFMerger();

		$modeleDoc = $this->getTableObjet('type_modeles_docs')->select(array('id' => $idModele))->current();

		$modeleGroupe = false;
		$isPDF = false;
		$urlGeneratedFile = "";
		$idsSuivis = array();
		if ($mode == 'suivis') {
			if ($modeleDoc->sousTypeModele == 'groupé') {
				$modeleGroupe = true;
			}
			$suivis = $this->getSuivisTable()->getSuivisByIds($idsResa);
			foreach ($suivis as $s) {
				if ($s->idResa) {
					$idsSuivis[$s->idResa][] = $s->id;
				} elseif ($s->idDp) {
					$idsSuivis[$s->idDp][] = $s->id;
				}
			}
		}

		//on aura un suivis par résa/dp
		if ($modeleGroupe) {
			$idsResa = array();
			foreach ($idsSuivis as $k => $idsS) {
				if (!empty($idsS)) {
					$idsResa[] = $idsS[0];
				}
			}
		}

		$idCampagneModeleDoc = !empty($params['idCampagneModeleDoc']) ? $params['idCampagneModeleDoc'] : 0;
		$idsMembresMenage = !empty($params['idsMembresMenage']) ? $params['idsMembresMenage'] : array();
		foreach ($idsResa as $row) {
			if ($mode == "facture" && is_array($row)) {
				$idResa = $row['idReservation'];
				$noFacture = $row['noFacture'];
			} else {
				$idResa = $row;
				$noFacture = "";
			}
			$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => true, 'mode' => $mode, 'idsSuivis' => $idsSuivis, 'idCampagneModeleDoc' => $idCampagneModeleDoc, 'idsMembresMenage' => $idsMembresMenage);
			$returnUrl = $this->genererModeleDocument($idResa, $noFacture, $idModele, $options);

			if ($returnUrl) {
				if (file_exists($returnUrl)) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : returnUrl=$returnUrl : existe");
					$pdf->addPDF($returnUrl, 'all');
					$isPDF = true;
				} else {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : returnUrl=$returnUrl : n'existe pas");
				}
			}
		}


		if ($isPDF) {
			$modele = $this->getTableObjet('type_modeles_docs')->select(array('id' => $idModele))->current();
			$outputMerge = getcwd()."/public/docs/modeles/output/toprint/".$modele->code."/";
			$pdf->merge('file', $outputMerge.'ALL_'.$modele->code.".pdf");

			$urlGeneratedFile = $this->getBaseUrl()."docs/modeles/output/toprint/".$modele->code."/".'ALL_'.$modele->code.".pdf";
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : outputMerge=$outputMerge");
		}

		return $urlGeneratedFile;
	}

	public function genererModeleDocForwardAction()
	{
		$params	= $this->getEvent()->getRouteMatch()->getParam('params');
		$url = "";
		if (!empty($params)) {
			$idResa = $params['idResa'];
			$idModele = $params['idModele'];
			$options = $params['options'];
			if ($idResa && $idModele && !empty($options)) {
				$url = $this->genererModeleDocument($idResa, "", $idModele, $options);
			}
		}
		return $url;
		exit();
	}

	## forwarder vers Etudiant/IndexController.php
	private function genererModeleDocumentFWD($idResa, $noFacture = "", $idModele, $options = array())
	{
		$url = $this->forward()->dispatch('Etudiant\Controller\Index', array(
											'action' => 'genererModeleDocForward',
											'params'	=> array('idResa' => $idResa,
																'idModele' => $idModele,
																'options' => $options,
																'noFacture' => $noFacture,
																),
							));
		return $url;
	}


	private function genererModeleDocument($idResa, $noFacture = "", $idModele, $options = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele noFacture=$noFacture options=".json_encode($options));
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		//factue => 1
		//recu => 2
		//extrait de compte => 3
		//quittance => 4
		//avoir => 5
		//options : urlReturn="RELATIVE"/:"ABSOLU"
		$urlReturn = !empty($options['urlReturn']) ? $options['urlReturn'] : "RELATIVE";
		$isImpressionEnLot = !empty($options['impressionEnLot']) ? true : false;//si on appel la fonction depuis le menu liste, impression

		$typeOutput = !empty($options['type']) ? $options['type'] : "";

		$lang = !empty($options['lang']) ? $options['lang'] : "";

		$modeListe = !empty($options['mode']) ? $options['mode'] : "";//dp si domiciliation sinon réservations

		$avecSignature = !empty($options['avecSignature']) ? $options['avecSignature'] : false;

		# infos rib envoyer via le post quand on génère le modèle depuis le bouton dans le formulaire campagne
		$postData = !empty($options['postData']) ? $options['postData'] : array();

		$idsSuivis = !empty($options['idsSuivis']) ? $options['idsSuivis'] : array();
		$idCampagneModeleDoc = !empty($options['idCampagneModeleDoc']) ? $options['idCampagneModeleDoc'] : 0;
		$idsMembresMenage = !empty($options['idsMembresMenage']) ? $options['idsMembresMenage'] : array();

		$resa = null;
		$dp = null;
		$idDp = null;
		$idSuivis = null;
		$suivis = array();
		if ($modeListe == 'dp') {
			$idDp = $idResa;
			$idResa = null;
			$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			$referentsDP = $this->getReferentsDP($idDp);
			foreach ($referentsDP as $ref) {
				if ($ref['_id'] == $dp->idUser) {
					$dp->referentDp = $ref['display_name'];
				}
			}
		} elseif ($modeListe == 'suivis') {
			$idSuivis = $idResa;
			$idResa = null;
			$suivis = $this->getSuivisTable()->getSuivisAllInfos($idSuivis, $adapter, array('modeleDoc' => true));
			//print_r($suivis);exit();
			if (!empty($suivis)) {
				if ($suivis['idResa'] > 0) {
					$idResa = $suivis['idResa'];
					$resa = $this->getResaTable()->getResaWithPms($idResa);
				} elseif ($suivis['idDp'] > 0) {
					$idDp = $suivis['idDp'];
					$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
				}
			}
		} else {
			$resa = $this->getResaTable()->getResaWithPms($idResa);
			if (!$resa) {
				return false;
			}
		}

		$logement = $batiment = null;
		if ($resa->idLogement) {
			$logement = $this->getLogementTable()->getLogement($resa->idLogement);
		}
		if ($logement) {
			$batiment = $this->getBatimentTable()->getBatiment($logement->idBatiment);
		}


		$tools = new Tools();
		if ($dp) {
			$idLocataire = $dp->idLocataire;
		} else {
			$idLocataire = $resa->idLocataire;
		}

		if ($dp) {
			$idCampagne = $dp->idCampagne;
		} else {
			$idCampagne = $resa->idCampagne;
		}



		$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, true, $idResa, $idCampagne, $idDp);

		$loc['email2'] = $loc['emailHec'];
		if ($loc['civilite'] == 1 || $loc['civilite'] == '1' /*|| $loc['civilite'] == 'Monsieur'*/) {
			$loc['civilite'] = "M";
		} elseif ($loc['civilite'] == 2 || $loc['civilite'] == '2' /*|| $loc['civilite'] == 'Madame'*/) {
			$loc['civilite'] = "Mme";
		}

		## User connecté au BO:
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$loc['loggedUser'] =  $user->getDisplayName();
		} else {
			$loc['loggedUser'] = '';
		}
		$loc['idReservation'] = $resa->id;

		##Recup des infos des membre de la meme famille si il s'agit d'un menage
		$membresMenageData = array();
		if($resa->idMenage > 0 && !empty($idsMembresMenage)) {
			$membresMenage = $this->getResaTable()->getMembresMenage($resa->idMenage, $all = true);
			foreach($membresMenage as $m) {
				if($m->id != $idResa && in_array($m->id, $idsMembresMenage)) {
					$mLoc = $this->getLocatairesTable()->getAllInfos($m->idLocataire, $adapter, true, $m->id, $m->idCampagne, 0);
					if($mLoc) {
						$mArr = get_object_vars($m);
						$membresMenageData[$m->id] = array_merge($mArr, $mLoc);
					}
				}
			}
		}

		## remplacer les valeurs vide pas vide
		$champsDynamiques = $this->getChampsFormulaireTable()->select(array('nature' => 'libre'));
		foreach ($champsDynamiques as $cd) {
			$key = $cd->nomXML ? $cd->nomXML : $cd->equivalentSql;
			if (!array_key_exists($key, $loc)) {
				$loc[$key] = "";
			}
			if(!empty($membresMenageData)) {
				foreach($membresMenageData as $k => $mLoc) {
					if (!array_key_exists($key, $mLoc)) {
						$membresMenageData[$k][$key] = "";
					}
				}
			}
		}

		## choix de logement
		if ($idResa) {
			$choix = $this->getResidencesTable()->getChoixResidences($idResa);
			$i = 1;
			foreach ($choix as $ch) {
				$loc['choix'.$i] = $ch->nom;
				$i++;
			}
		}

		## calcule age
		if (empty($loc['age']) && !empty($loc['dateNaissance'])) {
			$dateNaissance = str_replace('/', '-', $loc['dateNaissance']);
			$dateDebut = new \DateTime(date('Y-m-d'));
			$dateFin = new \DateTime($dateNaissance);
			$difference = $dateDebut->diff($dateFin);
			$age = $difference->format('%y');
			$loc['age'] = $age;
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire nom=$loc[nom] prenom=$loc[prenom] email=$loc[email] emailHec=$loc[emailHec] langue=$loc[langue]");
		if (!$lang) {
			## Prendre la langue préférée du locataire : FR ou EN dans les autres cas
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$lang	= $loc[langue] == 'FR' ? 'FR' : 'EN';
		}

		//recup user lié à reservations.idUser
		if ($resa && $resa->idUser) {
			$user = $this->getUserTable()->getUser($resa->idUser);
			if ($user) {
				$loc['idUser'] = $user->display_name;
			}
		}


		$conf = $this->getConfigurationTable()->getConfig(1);


		$modele = $this->getTableObjet('type_modeles_docs')->select(array('id' => $idModele))->current();
		if (!$modele) {
			return false;
		}
		//$isImpressionEnLot = $modele->imprimableEnLot;


		$modeleCode = $modele->code;
		$modeleName = '';

		if (!$modele->active) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode : abandon car desactive");
			return false;
		}


		//print_r($loc);

		if (!is_dir(getcwd()."/public/docs/modeles/output")) {
			mkdir(getcwd()."/public/docs/modeles/output");
		}
		$outputFolder = getcwd()."/public/docs/modeles/output/";


		//on récupère la résidence
		$idResidence = 0;
		$codeSite = "";

		if ($resa->idLogement) {
			## Une chambre est déjà allouée -> rechercher la résidence à partir de ce logement
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$residence = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
			if ($residence) {
				$idResidence	= $residence->idResidence;
			}
		} elseif ($resa->idTypeLogementAttribue) {
			## Pas de chambre allouee -> rechercher la résidence en passant par le type de logement attribué
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			$residenceDuType = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);
			if ($residenceDuType) {
				$idResidence = $residenceDuType->idResidence;
				$codeSite = $residenceDuType->idPMSResidence;
			}
		} elseif ($resa->codeSite) {
			## Pas de chambre allouee -> rechercher la résidence en passant par le PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			$codeSite = $resa->codeSite;

			$residence = $this->getResidencesTable()->getResidenceBy(array('idApiPms' => $resa->idApiPms, 'idPMS' => $codeSite));
			$idResidence = $residence ? $residence->id : 0;

			//print_r($resa->idTypeLogementAttribue);exit();

			$dateFacture = date('Y-m-d');

			if ($conf && $conf->bredea == 1 && $codeSite) {
				try {
					$bredea		= null;
					if ($resa) {
						$this->initPMS($resa->idApiPms ?: 1, $idResa);

						## Traitement en fonction du PMS
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						if ($this->pms) {
							if ($this->pms->getClassName() === "Bredea") {
								$bredea	= $this->pms;
							} elseif ($this->pms->getClassName() === "CeriFoyer") {
								## Rien à faire pour l'instant
							}
						}
					}
					if ($bredea) {
						##viaPMS $bredea = new BredeaSql();

						$typre = $resa->typre ? $resa->typre : 'R';
						$cData = array('codeSite' => $codeSite, 'numResa' => $resa->numResa, 'numDossier' => $resa->numDossier, 'typre' => $typre, 'noFacture' => $noFacture);
						$facture = $bredea->lireFacture($cData);
						if ($facture['jvt_dtfac']) {
							$dateFacture = $facture['jvt_dtfac'];
						}
						if($facture['jvt_typefact']) {
							## Modèles facture on vérifie si il ya un modèle pour les factures manuelle, si on on le prend si le type de facture est M
							$typeFacture = trim($facture['jvt_typefact']);
							if($typeFacture == 'M' && $idModele == 1) {
								$_modelesFolder = getcwd().'/public/docs/modeles/'.$modeleCode.'M/';
								$_files	= scandir($_modelesFolder, SCANDIR_SORT_DESCENDING);
								if ($_files) {
									$modeleCode .= 'M';
								}
							}
						}
						$bredea->closeConnect();
						$this->pms	= null;
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				}
			}
		}

		if (!$idResidence && $resa->residenceOrientation) {
			$idResidence = $resa->residenceOrientation;
		}

		if ($resa->residenceOrientation) {
			$residenceOr = $this->getResidencesTable()->getResidence($resa->residenceOrientation);
			if ($residenceOr) {
				$loc['residenceOrientation'] = $residenceOr->nom;
			}
		}


		if ($resa->codeSite) {
			$codeSite = $resa->codeSite;
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idLogement=".$resa->idLogement." idTypeLogementAttribue=".$resa->idTypeLogementAttribue." codeSite=".$resa->codeSite." idResidence=$idResidence idsResidences=".$modele->idsResidences);

		//on cherche si un modele est activer pour la residence
		$idsResidences = explode('|', $modele->idsResidences);//return un array
		if ($idResidence && in_array($idResidence, $idsResidences)) {
			//le modele est active pour cette residence
			//si aucun fichier associer, on prend juste les variable definis pour la residence si existent, sinon on prend les vars general
			//si un modele odt existe, avec une date active, on le prend
			// chemin des modeles par site : getcwd()."/public/docs/modeles/".$modele."/site/".$idResidence
			$modelesFolder = getcwd().'/public/docs/modeles/'.$modeleCode.'/site/'.$idResidence.'/';
			if (is_dir($modelesFolder)) {
				## Lecture des fichiers dans l'ordre décroissant
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$files	= scandir($modelesFolder, SCANDIR_SORT_DESCENDING);
				if ($files) {
					foreach ($files as $filename) {
						$dateModeleTS	= 0;
						if (preg_match("/^.*_([0-9]{8})\.odt$/", $filename, $regs)) {
							$dateModele	= $regs[1];
							if ($dateModele) {
								$dateModeleTS	= strtotime($dateModele);
							}
							if ($dateModeleTS) {
								if ($dateModeleTS > time()) {
									## Modele dans le futur - on exclut
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence filename=$filename dateModele=$dateModele : ignore car futur");
									continue;
								}
								$modeleName	= $filename;
								break;
							}
						}
					}
				}
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence modeleName=$modeleName");
		} else {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence : modele par site desactive");
		}

		if (!is_dir(getcwd()."/public/docs/locataires")) {
			mkdir(getcwd()."/public/docs/locataires");
		}

		if ($isImpressionEnLot) {
			if (!is_dir(getcwd()."/public/docs/modeles/output/toprint")) {
				mkdir(getcwd()."/public/docs/modeles/output/toprint");
			}
			if (!is_dir(getcwd()."/public/docs/modeles/output/toprint/".$modeleCode)) {
				mkdir(getcwd()."/public/docs/modeles/output/toprint/".$modeleCode);
			}

			$locataireFolder = getcwd()."/public/docs/modeles/output/toprint/".$modeleCode."/";
			$urlGeneratedFile = $this->getBaseUrl()."/docs/modeles/output/toprint/".$modeleCode."/";
		} elseif ($avecSignature) {
			$categorieCode	= "contratsSignes";
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads")) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads");
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$categorieCode)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$categorieCode);
			}

			$locataireFolder = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$categorieCode."/";
			$urlGeneratedFile = $this->getBaseUrl()."/docs/locataires/".$idLocataire."/uploads/".$categorieCode."/";
		} else {
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads")) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads");
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$modeleCode)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$modeleCode);
			}

			$locataireFolder = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$modeleCode."/";
			$urlGeneratedFile = $this->getBaseUrl()."/docs/locataires/".$idLocataire."/uploads/".$modeleCode."/";
		}


		$pdfName = $modeleCode.$lang.'_'.date('Ymd').'_'.$idLocataire;

		if (!$modeleName) {
			## si pas trouve pour la residence : recherche d'un modele global
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$modelesFolder = getcwd().'/public/docs/modeles/'.$modeleCode.'/';

			if (is_dir($modelesFolder)) {
				## Lecture des fichiers dans l'ordre décroissant
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$files	= scandir($modelesFolder, SCANDIR_SORT_DESCENDING);
				if ($files) {
					foreach ($files as $filename) {
						$dateModeleTS	= 0;
						if (preg_match("/^.*_([0-9]{8})\.odt$/", $filename, $regs)) {
							$dateModele	= $regs[1];
							if ($dateModele) {
								$dateModeleTS	= strtotime($dateModele);
							}
							if ($dateModeleTS) {
								if ($dateModeleTS > time()) {
									## Modele dans le futur - on exclut
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence filename=$filename dateModele=$dateModele : ignore car futur");
									continue;
								}
								$modeleName	= $filename;
								break;
							}
						}
					}
				}
			}
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence modeleName=$modeleName modelesFolder=$modelesFolder");

		## si modèles campagne, on cherche que celui là
		if ($idCampagneModeleDoc > 0) {
			$modeleName = null;
			$modelesFolder = getcwd().'/public/docs/modeles/'.$modeleCode.'/campagne/'.$idCampagneModeleDoc.'/';
			if (is_dir($modelesFolder)) {
				## Lecture des fichiers dans l'ordre décroissant
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$files	= scandir($modelesFolder, SCANDIR_SORT_DESCENDING);
				if ($files) {
					foreach ($files as $filename) {
						$dateModeleTS	= 0;
						if (preg_match("/^.*_([0-9]{8})\.odt$/", $filename, $regs)) {
							$dateModele	= $regs[1];
							if ($dateModele) {
								$dateModeleTS	= strtotime($dateModele);
							}
							if ($dateModeleTS) {
								if ($dateModeleTS > time()) {
									## Modele dans le futur - on exclut
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idCampagneModeleDoc=$idCampagneModeleDoc filename=$filename dateModele=$dateModele : ignore car futur");
									continue;
								}
								$modeleName	= $filename;
								break;
							}
						}
					}
				}
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire modeleCode=$modeleCode idResidence=$idResidence modeleName=$modeleName");
		}

		if (!$modeleName) {
			return false;
		}

		if ($lang) {
			$nomModeleODT = pathinfo($modeleName, PATHINFO_FILENAME);
			if (file_exists($modelesFolder.$nomModeleODT.'_'.$lang.'.odt')) {
				$modeleName = $nomModeleODT.'_'.$lang.'.odt';
			}
		}


		$odf = new odf($modelesFolder.$modeleName, array('ZIP_PROXY' => 'PhpZipProxy'));

		## set modele vars
		$modeleVars = $this->getTableObjet('config_modeles_docs')->select(array('idResidence' => 0))->current();
		if(!$modeleVars) {
			$modeleVars = new \stdClass();
		}
		$dossierLogo = 'exports';//repertoire par defaut du logo, menu systeme
		$imageSignatureCampagne = '';
		if ($idResidence) {
			$siteVars = $this->getTableObjet('config_modeles_docs')->select(array('idResidence' => $idResidence))->current();
			if ($siteVars) {
				if ($siteVars->nomStructure) {
					$modeleVars->nomStructure = $siteVars->nomStructure;
				}
				if ($siteVars->responsableStructure) {
					$modeleVars->responsableStructure = $siteVars->responsableStructure;
				}
				if ($siteVars->adresseStructure1) {
					$modeleVars->adresseStructure1 = $siteVars->adresseStructure1;
				}
				if ($siteVars->adresseStructure2) {
					$modeleVars->adresseStructure2 = $siteVars->adresseStructure2;
				}
				if ($siteVars->codePostalStructure) {
					$modeleVars->codePostalStructure = $siteVars->codePostalStructure;
				}
				if ($siteVars->villeStructure) {
					$modeleVars->villeStructure = $siteVars->villeStructure;
				}
				if ($siteVars->telephoneStructure) {
					$modeleVars->telephoneStructure = $siteVars->telephoneStructure;
				}
				if ($siteVars->faxStructure) {
					$modeleVars->faxStructure = $siteVars->faxStructure;
				}
				if ($siteVars->emailStructure) {
					$modeleVars->emailStructure = $siteVars->emailStructure;
				}
				if ($siteVars->logo && file_exists(getcwd()."/public/img/modeles/".$idResidence."/".$siteVars->logo)) {
					$modeleVars->logo = $siteVars->logo;
					$dossierLogo = "modeles/".$idResidence;
				}
				if ($siteVars->imageSignature) {
					$modeleVars->imageSignature = $siteVars->imageSignature;
				}
				if ($siteVars->imageTampon) {
					$modeleVars->imageTampon = $siteVars->imageTampon;
				}
			}
		}

		if ($idCampagne > 0) {
			$campVar = $this->getTableObjet('config_modeles_docs')->select(array('idCampagne' => $idCampagne))->current();
			if ($campVar) {
				if ($campVar->logo && file_exists(getcwd()."/public/img/modeles/campagnes/".$idCampagne."/".$campVar->logo)) {
					$modeleVars->logo = $campVar->logo;
					$dossierLogo = "modeles/campagnes/".$idCampagne;
				}
				if ($campVar->imageSignature) {
					$modeleVars->imageSignature = $campVar->imageSignature;
					$imageSignatureCampagne = $campVar->imageSignature;
				}
			}
		}

		$odfVars = $odf->getVarsAndSegments();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire odfVars=".json_encode($odfVars));

		if ($modeleVars) {
			$odf->setVars('nomStructure', $modeleVars->nomStructure, false, 'UTF8');
			$odf->setVars('responsableStructure', $modeleVars->responsableStructure, false, 'UTF8');
			$odf->setVars('adresseStructure1', $modeleVars->adresseStructure1, false, 'UTF8');
			$odf->setVars('adresseStructure2', $modeleVars->adresseStructure2, false, 'UTF8');
			$odf->setVars('codePostalStructure', $modeleVars->codePostalStructure);
			$odf->setVars('villeStructure', $modeleVars->villeStructure, false, 'UTF8');
			$odf->setVars('telephoneStructure', $modeleVars->telephoneStructure);
			$odf->setVars('faxStructure', $modeleVars->faxStructure, false, 'UTF8');
			$odf->setVars('emailStructure', $modeleVars->emailStructure);
			//images
			$logo = $modeleVars->logo;
			$folder = getcwd()."/public/img/".$dossierLogo."/";
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idModele=$idModele idLocataire=$idLocataire logo=$logo dossierLogo=$dossierLogo");

			if (array_key_exists('{logo}', $odfVars)) {
				if ($logo && file_exists($folder.$logo)) {
					$odf->setImage('logo', $folder.$logo);
				} else {
					$odf->setVars('logo', '');
				}
			}
			//imageSignature
			if (array_key_exists('{imageSignature}', $odfVars)) {
				$imageSignature = $modeleVars->imageSignature;
				$folder = getcwd()."/public/img/modeles/";
				$imageSignaturePtr	= '';
				if ($idResidence && $imageSignature) {
					## Tentons le spécifique
					## ~~~~~~~~~~~~~~~~~~~~~
					if (file_exists("$folder$idResidence/$imageSignature")) {
						$imageSignaturePtr	= "$folder$idResidence/$imageSignature";
					} elseif (file_exists("$folder$imageSignature")) {
						$imageSignaturePtr	= "$folder$imageSignature";
					}
				}
				//image signature campagne
				if ($idCampagne && $imageSignatureCampagne) {
					## Tentons le spécifique
					## ~~~~~~~~~~~~~~~~~~~~~
					if (file_exists("$folder"."campagnes/"."$idCampagne/$imageSignature")) {
						$imageSignaturePtr	= "$folder"."campagnes/"."$idCampagne/$imageSignature";
					}
				}
				if ($imageSignaturePtr) {
					$odf->setImage('imageSignature', $imageSignaturePtr);
				} else {
					$odf->setVars('imageSignature', '');
				}
			}

			if (array_key_exists('{imageTampon}', $odfVars)) {
				//imageTampon
				$imageTampon = $modeleVars->imageTampon;
				$folder = getcwd()."/public/img/modeles/";
				$imageTamponPtr	= '';
				if ($idResidence && $imageTampon) {
					## Tentons le spécifique
					## ~~~~~~~~~~~~~~~~~~~~~
					if (file_exists("$folder$idResidence/$imageTampon")) {
						$imageTamponPtr	= "$folder$idResidence/$imageTampon";
					} elseif (file_exists("$folder$imageTampon")) {
						$imageTamponPtr	= "$folder$imageTampon";
					}
				}
				if ($imageTamponPtr) {
					$odf->setImage('imageTampon', $imageTamponPtr);
				} else {
					$odf->setVars('imageTampon', '');
				}
			}
		} else {
			if (array_key_exists('{logo}', $odfVars)) {
				$odf->setVars('logo', '');
			}
			if (array_key_exists('{imageSignature}', $odfVars)) {
				$odf->setVars('imageSignature', '');
			}
			if (array_key_exists('{imageTampon}', $odfVars)) {
				$odf->setVars('imageTampon', '');
			}
		}

		##controle modèle MSEPA, si on a pas les infos RIB, on exporte pas :
		if($modele->code == "MSEPA" && $modele->obligatoire == 1) {
			$genererSEPA = false;
			if(!empty($loc['rib_rib']) && $loc['rib_rib'] != '' && !empty($loc['rib_bic']) && $loc['rib_bic'] != '' && !empty($loc['rib_nomrib']) && $loc['rib_nomrib'] != '') {
				$genererSEPA = true;
			}
			if(!empty($loc['ibanSEPA']) && $loc['ibanSEPA'] != '' && !empty($loc['bicSEPA']) && $loc['bicSEPA'] != '') {
				$genererSEPA = true;
			}

			if(!empty($postData['rib_rib']) && $postData['rib_rib'] != '' && !empty($postData['rib_bic']) && $postData['rib_bic'] != '' && !empty($postData['rib_nomrib']) && $postData['rib_nomrib'] != '') {
				$loc = array_merge($loc,$postData);
				$loc['rib_iban'] = $postData['rib_rib'];
				$genererSEPA = true;
			}

			if(!$genererSEPA) {
				return array('msg' => "Il manque des valeurs dans les champs RIB");
			}

		}

		## Lecture du type de logement
		$logementType = $this->getTypelogementTable()->getTypeLogement($resa->idTypeLogementAttribue);
		$logementTypeNom	= ($lang == 'FR') ? $logementType->nom : $logementType->nomEn;
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire logementTypeId=".$resa->idTypeLogementAttribue." logementTypeNom=$logementTypeNom");
		#$odf->setVars('log_typelogement', $logementTypeNom, false, 'UTF8');
		$loc[log_type]	= $logementTypeNom;
		## Bidouille affreuse mais tant que je ne comprends pas comment on génére des variables dans les .pdf !!!
		//$loc[emailHec]	= $logementTypeNom;
		## Bidouille affreuse mais tant que je ne comprends pas comment on génére des variables dans les .pdf !!!

		##recup du loyer
		$tarifsDefault = $this->getTableObjet("tarifs")->select(array('idTypeLogement' => $resa->idTypeLogementAttribue, 'idCampagne' => $resa->idCampagne, 'default' => '1'))->current();
		$loyer = "";
		if ($tarifsDefault) {
			$loyer = $tarifsDefault->loyer;
		}
		$loc['loyer'] = $loyer;
		$loc['loyerTypeLogementAttribue'] = $loyer;

		## set locataire vars
		foreach ($loc as $key => $value) {
			if (is_string($value)) {
				$value = nl2br($value);
				if ($modele->code == "MSEPS" && $key == "rumSEPA") {
					## Ignorer le RUM de la BDD car il sera regénéré
					continue;
				}
				## syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire loc: key=$key value=$value");
				$value = str_replace('&', ' ', $value);
				$odf->setVars($key, $value, false, 'UTF8');
			}
		}

		## Set Suivis vars
		if (!empty($suivis)) {
			foreach ($suivis as $key => $value) {
				$value = nl2br($value);
				## syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire suivis: key=$key value=$value");
				$odf->setVars($key, $value, false, 'UTF8');
			}
		}

		## set logements vars
		if ($logement && is_object($logement)) {
			$logeArr = get_object_vars($logement);
			foreach ($logeArr as $key => $value) {
				if ($key == 'loyer' && !$value) {
					continue;
				}
				$value = nl2br($value);
				## syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire logements: key=$key value=$value");
				$odf->setVars($key, $value, false, 'UTF8');
				$odf->setVars('logement_'.$key, $value, false, 'UTF8');
			}
		}

		## Infos membres menages
		if(!empty($membresMenageData)) {
			$odfVarsAndSegement = $odf->getVarsAndSegments();
			if (in_array('BEGIN_lignesMembresMenage', $odfVarsAndSegement) || array_key_exists('BEGIN_lignesMembresMenage', $odfVarsAndSegement)) {
				$segmentMM = $odf->setSegment('lignesMembresMenage');
				foreach ($membresMenageData as $idResaM => $mData) {
					foreach ($mData as $key => $value) {
						$value = nl2br($value);
						$segmentMM->setVars($key, $value, false, 'UTF8');
					}
					$segmentMM->merge();
				}
				$odf->mergeSegment($segmentMM);
			}
		}

		//$odfVarsAndSegements = $odf->getVarsAndSegments();
		//print_r($odfVarsAndSegements);exit();

		## Suivis coche dans un bloc
		if ($modeListe == "suivis") {
			$odfVarsAndSegement = $odf->getVarsAndSegments();
			if (in_array('BEGIN_lignesSuivis', $odfVarsAndSegement) || array_key_exists('BEGIN_lignesSuivis', $odfVarsAndSegement)) {
				$segmentLS = $odf->setSegment('lignesSuivis');
				$idLigne = $idDp ? $idDp : $idResa;
				if (!empty($idsSuivis[$idLigne])) {
					$idsDeSuivis = $idsSuivis[$idLigne];
					foreach ($idsDeSuivis as $idS) {
						$suivisRow = $this->getSuivisTable()->getSuivisAllInfos($idS, $adapter, array('modeleDoc' => true, 'langue' => $loc['langue']));
						foreach ($suivisRow as $key => $value) {
							$value = nl2br($value);
							$segmentLS->setVars($key, $value, false, 'UTF8');
						}
						$segmentLS->merge();
					}
				}
				$odf->mergeSegment($segmentLS);
			}
		}

		## formulaires campagne
		if (($resa || $dp) && ($idModele == 8 || $modele->code == "FORM" || $modele->code == "FRMSV") && $conf->mode != 'HEC') {

			//print_r($odf->getVarsAndSegments());exit();

			$odfSegments = array();
			if ($idModele == 8 || $modele->code == "FORM") {
				//code du modèle formulaire résa = FORM
				//$segmentFRM = $odf->setSegment('formulaires');

				$odfVarsAndSegement = $odf->getVarsAndSegments();// var : {var_name}, segement : BEGIN_segement_name sans les {}
				if (in_array('BEGIN_formulaires', $odfVarsAndSegement)) {
					$odfSegments['FRM'] = 'formulaires';
				}
				//on verifie si on a un type de suivis comme segment
				$typesSuivis = $this->getListeTypesSuivis();
				foreach ($typesSuivis as $idTS => $typeSuivis) {
					$segment_name = str_replace(' ', '_', $tools->removeAccentOnly(trim($typeSuivis)));
					if (in_array('BEGIN_'.$segment_name, $odfVarsAndSegement)) {
						$odfSegments['TS_'.$idTS] = $segment_name;
					}
				}
			}
			//print_r($odfSegments);exit();
			//print_r($odf->getVarsAndSegments());exit();
			foreach ($odfSegments as $codeSeg => $segmentName) {
				$idTypeSuivis = null;
				if (strpos($codeSeg, 'TS_') !== false) {
					$idTypeSuivis = str_replace('TS_', '', $codeSeg);
				}
				$frmReturn = $this->getFormulairesResaHtml($resa->id, $dp->id, array('idTypeSuivis' => $idTypeSuivis));
				$formsName = $frmReturn['formsName'];
				$formsArray = $frmReturn['formsArray'];

				$segmentFRM = $odf->setSegment($segmentName);
				//print_r($segmentFRM->getChildrens());continue;
				//print_r($segmentFRM);exit();
				$segmentChildren = $segmentFRM->getChildrens();
				if ($segmentName == "formulaires") {
					$formRowsSeg = 'formRows';
				} else {
					$formRowsSeg = 'formRows_'.$segmentName;
				}
				//pour eviter l exception Segement child not found
				if (!array_key_exists($formRowsSeg, $segmentChildren)) {
					continue;
				}
				foreach ($formsArray as $formId => $frmRows) {
					$frmName = $formsName[$formId];
					$segmentFRM->setVars("formName", $frmName, false, 'UTF8');
					foreach ($frmRows as $frmCols) {
						if (!empty($frmCols[1])) {
							$segmentFRM->$formRowsSeg->setVars("label1", !empty($frmCols[1]['label']) ? $frmCols[1]['label'] : "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur1", !empty($frmCols[1]['valeur']) ? $frmCols[1]['valeur'] : "", false, 'UTF8');
						} else {
							$segmentFRM->$formRowsSeg->setVars("label1", "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur1", "", false, 'UTF8');
						}
						if (!empty($frmCols[2])) {
							$segmentFRM->$formRowsSeg->setVars("label2", !empty($frmCols[2]['label']) ? $frmCols[2]['label'] : "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur2", !empty($frmCols[2]['valeur']) ? $frmCols[2]['valeur'] : "", false, 'UTF8');
						} else {
							$segmentFRM->$formRowsSeg->setVars("label2", "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur2", "", false, 'UTF8');
						}
						if (!empty($frmCols[3])) {
							$segmentFRM->$formRowsSeg->setVars("label3", !empty($frmCols[3]['label']) ? $frmCols[3]['label'] : "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur3", !empty($frmCols[3]['valeur']) ? $frmCols[3]['valeur'] : "", false, 'UTF8');
						} else {
							$segmentFRM->$formRowsSeg->setVars("label3", "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur3", "", false, 'UTF8');
						}
						if (!empty($frmCols[4])) {
							$segmentFRM->$formRowsSeg->setVars("label4", !empty($frmCols[4]['label']) ? $frmCols[4]['label'] : "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur4", !empty($frmCols[4]['valeur']) ? $frmCols[4]['valeur'] : "", false, 'UTF8');
						} else {
							$segmentFRM->$formRowsSeg->setVars("label4", "", false, 'UTF8');
							$segmentFRM->$formRowsSeg->setVars("valeur4", "", false, 'UTF8');
						}

						if (!empty($frmCols[1]) || !empty($frmCols[2]) || !empty($frmCols[3]) || !empty($frmCols[4])) {
							$segmentFRM->$formRowsSeg->merge();
						}

						## choix de logements
						if (!empty($frmCols[1]) && !empty($frmCols[1]['choix'])) {
							$choixRows = $frmCols[1]['choix'];
							foreach ($choixRows as $choixRow) {
								$segmentFRM->$formRowsSeg->setVars("label1", !empty($choixRow['label']) ? $choixRow['label'] : "", false, 'UTF8');
								$segmentFRM->$formRowsSeg->setVars("valeur1", !empty($choixRow['valeur']) ? $choixRow['valeur'] : "", false, 'UTF8');
								$segmentFRM->$formRowsSeg->merge();
							}
						}
					}
					//$segmentFRM->formRows->setVars("test", 'erere',false,'UTF8');
					//$segmentFRM->formRows->merge();

					$segmentFRM->merge();
				}
				$odf->mergeSegment($segmentFRM);
			}
		}


		$odfVarsAndSegements = $odf->getVarsAndSegments();

		#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire loc=".json_encode($loc));
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire");

		## resa
		$residence = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
		if ($residence) {
			$odf->setVars('batiment', $residence->batiment, false, 'UTF8');
			$odf->setVars('residence', $residence->residence, false, 'UTF8');

			$residenceFull	= $this->getResidencesTable()->getResidence($residence->idResidence);
			$odf->setVars('residence_nom', $residenceFull->residence, false, 'UTF8');
			$odf->setVars('residence_adresse', $residenceFull->adresse, false, 'UTF8');
			$odf->setVars('residence_codePostal', $residenceFull->codePostal, false, 'UTF8');
			$odf->setVars('residence_ville', $residenceFull->ville, false, 'UTF8');
			$odf->setVars('residence_telephone', $residenceFull->telephone, false, 'UTF8');
			$odf->setVars('residence_email', $residenceFull->email, false, 'UTF8');
			$odf->setVars('ribSite', $residenceFull->ribSite, false, 'UTF8');
			$odf->setVars('bicSite', $residenceFull->bicSite, false, 'UTF8');
		}

		## remonte tout les infos résidenc
		if($idResidence) {
			$residenceVars	= $this->getResidencesTable()->getResidence($idResidence);
			if($residenceVars) {
				foreach($residenceVars as $vr => $vl) {
					$odf->setVars('residence_'.$vr, $vl, false, 'UTF8');
				}
				## Nb de TS ayant accès à la résidence (peu importe la campagne)
				$nbTS = $this->getResidencesTable()->getNombreGestionnaireDeResidence($idResidence);
				$odf->setVars('residence_nbTS', $nbTS, false, 'UTF8');
				## Nb de dossiers présents à l'instant T
				$nbPresents = $this->getResaTable()->getTotalPresents($idResidence);
				$odf->setVars('residence_nbPresents', $nbPresents, false, 'UTF8');
				## Nb de logements sur la résidence
				$nbLoge = $this->getLogementTable()->getTotalLogementDeResidence($idResidence);
				$odf->setVars('residence_nbLogements', $nbLoge, false, 'UTF8');
			}
		}
		#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire resa=".json_encode($resa));

		//infor resa
		$resaArr = array();
		if ($resa) {
			$resaArr = get_object_vars($resa);
		}
		if ($resa->dateDemandeReservation) {
			$odf->setVars("dateDemandeReservation", date('d/m/Y', strtotime($resa->dateDemandeReservation)), false, 'UTF8');
		} else {
			$odf->setVars("dateDemandeReservation", "", false, 'UTF8');
		}
		if ($resa->dateArrivee) {
			$odf->setVars("dateArrivee", date('d/m/Y', strtotime($resa->dateArrivee)), false, 'UTF8');
			$mois = date('m', strtotime($resa->dateArrivee));
			if (strlen($mois == 1)) {
				$mois = '0'.$mois;
			}
			$listeMois = $tools->listeMois();
			$moisArrivee = !empty($listeMois[$mois]) ? $listeMois[$mois] : $mois;
			$odf->setVars("moisArrivee", $moisArrivee, false, 'UTF8');
		} else {
			$odf->setVars("dateArrivee", "", false, 'UTF8');
			$odf->setVars("moisArrivee", "", false, 'UTF8');
		}
		if ($resa->dateDepart && $resa->dateDepart != "0000-00-00" && $tools->isValideDate($resa->dateDepart)) {
			$odf->setVars("dateDepart", date('d/m/Y', strtotime($resa->dateDepart)), false, 'UTF8');
		} else {
			$odf->setVars("dateDepart", "", false, 'UTF8');
		}
		if ($resa->dateArriveeTheorique) {
			$odf->setVars("dateArriveeTheorique", date('d/m/Y', strtotime($resa->dateArriveeTheorique)), false, 'UTF8');
			$mois = date('m', strtotime($resa->dateArriveeTheorique));
			if (strlen($mois == 1)) {
				$mois = '0'.$mois;
			}
			$listeMois = $tools->listeMois();
			$moisArrivee = !empty($listeMois[$mois]) ? $listeMois[$mois] : $mois;
			$odf->setVars("moisArriveeTheorique", $moisArrivee, false, 'UTF8');
		} else {
			$odf->setVars("dateArriveeTheorique", "", false, 'UTF8');
			$odf->setVars("moisArriveeTheorique", "", false, 'UTF8');
		}
		if ($resa->dateDepartTheorique) {
			$odf->setVars("dateDepartTheorique", date('d/m/Y', strtotime($resa->dateDepartTheorique)), false, 'UTF8');
		} else {
			$odf->setVars("dateDepartTheorique", "", false, 'UTF8');
		}

		## choix de type logement
		if ($resa) {
			$nbrChoix = $this->getChoixTable()->getChoixDeReservation($resa->id);

			if ($nbrChoix->count() > 0) {
				for ($s = 1;$s <= $nbrChoix->count();$s++) {
					$c = $this->getChoixTable()->getChoixByResaNumero($idResa, $s);
					if ($c) {
						$champChoix = "typeLogement".$s;
						$choixVal = ($loc && $loc['langue'] == "UK") ? $c->typeLogementEn : $c->typeLogement;
						$odf->setVars($champChoix, $choixVal, false, 'UTF8');
					}
				}
			}
		}
		## fin choix de type de logement

		$odf->setVars("numeroChambre", $resa->numeroChambre, false, 'UTF8');
		if ($batiment) {
			$odf->setVars("numeroBatiment", $batiment->numero, false, 'UTF8');
		}

		if ($resa->idGroupeResa) {
			$odf->setVars("total_redevance", "", false, 'UTF8');
		}
		
		## Si on cherche les infos de la DP en mode résa
		if (!$dp) {
			$campagneDp = $this->getTableObjet('campagnes')->select(array('utiliserDpPourResa' => '1'))->current();
			$dp = $this->getTableObjet('domiciliations')->select(array('idLocataire' => $idLocataire, 'idCampagne' => $campagneDp->id, 'archive' => '0', 'etat' => '1'))->current();
		}

		## dates DP
		if ($dp) {
			if ($dp->dateEntree) {
				$odf->setVars("dateEntree", date('d/m/Y', strtotime($dp->dateEntree)), false, 'UTF8');
			} else {
				$odf->setVars("dateEntree", "", false, 'UTF8');
			}

			if ($dp->dateSortie) {
				$odf->setVars("dateSortie", date('d/m/Y', strtotime($dp->dateSortie)), false, 'UTF8');
			} else {
				$odf->setVars("dateSortie", "", false, 'UTF8');
			}

			//dateDebutValidite,dateFinValidite
			if ($dp->dateDebutValidite) {
				$odf->setVars("dateDebutValidite", date('d/m/Y', strtotime($dp->dateDebutValidite)), false, 'UTF8');
			} else {
				$odf->setVars("dateDebutValidite", "", false, 'UTF8');
			}
			if ($dp->dateFinValidite) {
				$odf->setVars("dateFinValidite", date('d/m/Y', strtotime($dp->dateFinValidite)), false, 'UTF8');
			} else {
				$odf->setVars("dateFinValidite", "", false, 'UTF8');
			}

			//recup premier DP
			$firstDp = $this->getDomiciliationsTable()->getLocFirstDp($dp->idLocataire);
			if ($firstDp && $firstDp->dateEntree) {
				$odf->setVars("dateEntreePremierDp", date('d/m/Y', strtotime($firstDp->dateEntree)), false, 'UTF8');
			} else {
				$odf->setVars("dateEntreePremierDp", "", false, 'UTF8');
			}

			//autres champs
			$odf->setVars("referentDp", $dp->referentDp, false, 'UTF8');
			$odf->setVars("nomEtat", $dp->nomEtat, false, 'UTF8');
			$odf->setVars("nomMotif", $dp->nomMotif, false, 'UTF8');
			if ($dp->docName) {
				$odf->setVars("cerfaDp", "Oui", false, 'UTF8');
			} else {
				$odf->setVars("cerfaDp", "Non", false, 'UTF8');
			}

			## CodeBarre DP
			if (strlen($dp->idLocataire) < 6) {
				$add0 = 6 - strlen($dp->idLocataire);
				$ch = "";
				for ($i = 0; $i < $add0; $i++) {
					$ch .= "0";
				}

				$numIdLocataire = $ch . $dp->idLocataire;
			}
			if (strlen($dp->idCarte) < 6) {
				$add0 = 6 - strlen($dp->idCarte);
				$ch = "";
				for ($i = 0; $i < $add0; $i++) {
					$ch .= "0";
				}

				$numIdCarte = $ch . $dp->idCarte;
			}
			$codeBarreText = $numIdLocataire . "-" . $numIdCarte;

			$fileCodeBarreDP = getcwd()."/public/docs/locataires/".$idLocataire."/carte/".$codeBarreText.".jpeg";
			if (file_exists($fileCodeBarreDP)) {
				$odf->setImage('codeBarreDP', $this->getBaseUrl()."/docs/locataires/".$idLocataire."/carte/".$codeBarreText.".jpeg", '0.5', '0.5', '0.5');
			} else {
				$odf->setVars('codeBarreDP', '', false, 'UTF8');
			}
		}

		$odf->setVars('date_now', date('d/m/Y'), false, 'UTF8');

		## Période début et fin période de facturation des prestation calculées
		$prestaCalculeRows = $this->getPrestaTable()->getPrestationsDeResa($idResa, 'facture');
		$prestaCalculeFacture = !empty($prestaCalculeRows) ? $prestaCalculeRows[sizeof($prestaCalculeRows) - 1] : null;
		if ($prestaCalculeFacture) {
			if ($prestaCalculeFacture->dateDebutPF && $prestaCalculeFacture->dateDebutPF != "0000-00-00" && $tools->isValideDate($prestaCalculeFacture->dateDebutPF)) {
				$odf->setVars("dateDebutPF", date('d/m/Y', strtotime($prestaCalculeFacture->dateDebutPF)), false, 'UTF8');
			} else {
				$odf->setVars("dateDebutPF", '', false, 'UTF8');
			}

			if ($prestaCalculeFacture->dateFinPF && $prestaCalculeFacture->dateFinPF != "0000-00-00" && $tools->isValideDate($prestaCalculeFacture->dateFinPF)) {
				$odf->setVars("dateFinPF", date('d/m/Y', strtotime($prestaCalculeFacture->dateFinPF)), false, 'UTF8');
			} else {
				$odf->setVars("dateFinPF", '', false, 'UTF8');
			}
		} else {
			$odf->setVars("dateDebutPF", '', false, 'UTF8');
			$odf->setVars("dateFinPF", '', false, 'UTF8');
		}

		if ($idModele == 11 && $logement) {
			$odf->setVars('numeroLogement', $logement->numero, false, 'UTF8');
			$odf->setVars('superficie', $logement->superficie, false, 'UTF8');
			$odf->setVars('loyerHC', $logement->loyerHC, false, 'UTF8');
			$odf->setVars('complementLoyer', $logement->complementLoyer, false, 'UTF8');
			$odf->setVars('charges', $logement->charges, false, 'UTF8');
			$odf->setVars('loyer', $logement->loyer, false, 'UTF8');
		}

		## recup charges
		$charges = $this->getChargesTable()->getChargesRepartisDeResa($idResa);
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] count_charges=".count($charges));

		if (!empty($charges)) {

			if (0) {
				## Tableau des provisions
				## ~~~~~~~~~~~~~~~~~~~~~~
				$segmentCharge = $odf->setSegment('ligneCharge');
				$totalMontantReel = $totalMontantProvision = $totalMontantRepartition = 0;
				$dateFinPeriodeTS	= 0;
				foreach ($charges as $charge) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] charges=".json_encode($charges));
					if (!empty($charge->idCompteurDebut)) {
						$charge->presence = 0;
						$compteurDeb = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurDebut);
						$compteurFin = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurFin);
						$charge->baseIndividuel = $compteurFin->valeurCompteur - $compteurDeb->valeurCompteur;
					} elseif (!empty($charge->idCompteurFin)) {
						$compteurFin = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurFin);
						$charge->baseIndividuel = $compteurFin->valeurCompteur;
					}
					if (!$dateFinPeriodeTS) {
						$dateFinPeriodeTS	= strtotime($charge->dateFinPeriode);
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] charge=".json_encode($charge));
					$odf->setVars('dateDebutPeriode', date('d/m/Y', strtotime($charge->dateDebutPeriode)), false, 'UTF8');
					$odf->setVars('dateFinPeriode', date('d/m/Y', strtotime($charge->dateFinPeriode)), false, 'UTF8');
					if ($charge->montantProvision) {
						$segmentCharge->setVars('nomCharge', $charge->nomCharge, false, 'UTF8');
						$segmentCharge->setVars('montantReelGlobal', number_format($charge->montantReelGlobal, 2), false, 'UTF8');
						$segmentCharge->setVars('baseIndividuel', number_format($charge->baseIndividuel, 2), false, 'UTF8');
						$segmentCharge->setVars('baseTotal', number_format($charge->baseTotal, 2), false, 'UTF8');
						$segmentCharge->setVars('presence', $charge->presence, false, 'UTF8');
						$segmentCharge->setVars('montantReel', number_format($charge->montantReel, 2), false, 'UTF8');
						$segmentCharge->setVars('montantProvision', number_format($charge->montantProvision, 2), false, 'UTF8');
						$segmentCharge->setVars('montantRepartition', number_format($charge->montantRepartition, 2), false, 'UTF8');

						$segmentCharge->merge();
					}

					$totalMontantProvision += $charge->montantProvision;
					/* Supprimé par AK car le montant réel devrait être calculé à partir des lignes de charge
					$totalMontantReel += $charge->montantReel;
					*/
				}
				$odf->mergeSegment($segmentCharge);
			}

			## Periode d'occupation pour les régularisation de charges
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($resa->dateArrivee && $resa->dateArrivee != "0000-00-00" && $tools->isValideDate($resa->dateArrivee)) {
				$odf->setVars("dateDebutOccupation", date('d/m/Y', strtotime($resa->dateArrivee)), false, 'UTF8');
			} else {
				$odf->setVars("dateDebutOccupation", "", false, 'UTF8');
			}
			if ($resa->dateDepart && $resa->dateDepart != "0000-00-00" && $tools->isValideDate($resa->dateDepart)) {
				$odf->setVars("dateFinOccupation", date('d/m/Y', strtotime($resa->dateDepart)), false, 'UTF8');
			} else {
				$odf->setVars("dateFinOccupation", date('d/m/Y', $dateFinPeriodeTS), false, 'UTF8');
			}
			##charges prov
			$chargesProvRet = $this->getChargesTable()->getChargesProvRepartisDeResa($idResa);
			##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] count_chargesProv=".count($chargesProvRet));
			if (!empty($chargesProvRet)) {
				$chargesProv = $chargesProvRet['provision'];
				$chargeRow = $chargesProvRet['charge'];
				if (!empty($chargesProv)) {
					$segmentChargeProv = $odf->setSegment('ligneChargeProv');

					foreach ($chargesProv as $idPresta => $chargeDePresta) {
						foreach ($chargeDePresta as $charge) {
							$segmentChargeProv->setVars('nomCharge', $charge['nomCharge'], false, 'UTF8');
							$segmentChargeProv->setVars('montantProvision', number_format($charge['montantProvision'], 2, '.', ' '), false, 'UTF8');
							$segmentChargeProv->setVars('dateDebut', date('d/m/Y', strtotime($charge['dateDebut'])), false, 'UTF8');
							$segmentChargeProv->setVars('dateFin', date('d/m/Y', strtotime($charge['dateFin'])), false, 'UTF8');
							$segmentChargeProv->setVars('dateProvision', date('d/m/Y', strtotime($charge['dateFacture'])), false, 'UTF8');
							$segmentChargeProv->merge();
						}
					}
					$odf->mergeSegment($segmentChargeProv);
				} else {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] count_charges : zero");
					$segmentChargeProv = $odf->setSegment('ligneChargeProv');
					$segmentChargeProv->setVars('nomCharge', ' ', false, 'UTF8');
					$segmentChargeProv->setVars('montantProvision', ' ', false, 'UTF8');
					$segmentChargeProv->setVars('dateDebut', ' ', false, 'UTF8');
					$segmentChargeProv->setVars('dateFin', ' ', false, 'UTF8');
					$segmentChargeProv->setVars('dateProvision', ' ', false, 'UTF8');
					$segmentChargeProv->merge();
					$odf->mergeSegment($segmentChargeProv);
				}
			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] count_charges : zero");
				$segmentChargeProv = $odf->setSegment('ligneChargeProv');
				$segmentChargeProv->setVars('nomCharge', ' ', false, 'UTF8');
				$segmentChargeProv->setVars('montantProvision', ' ', false, 'UTF8');
				$segmentChargeProv->setVars('dateDebut', ' ', false, 'UTF8');
				$segmentChargeProv->setVars('dateFin', ' ', false, 'UTF8');
				$segmentChargeProv->setVars('dateProvision', ' ', false, 'UTF8');
				$segmentChargeProv->merge();
				$odf->mergeSegment($segmentChargeProv);
			}

			## Tableau du détail des charges
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$chargesDetail = $this->getChargesTable()->getChargesRepartisDeResa($idResa, 'calcule');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] count_chargesDetail=".count($chargesDetail));
			#$segmentDetailCharge = $odf->setSegment('detailCharge');
			$segmentDetailCharge = $odf->setSegment('ligneCharge');
			foreach ($chargesDetail as $charge) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] charge=".json_encode($charge));
				if (!empty($charge->idCompteurDebut)) {
					$charge->presence = 0;
					$compteurDeb = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurDebut);
					$compteurFin = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurFin);
					$charge->baseIndividuel = $compteurFin->valeurCompteur - $compteurDeb->valeurCompteur;
				} elseif (!empty($charge->idCompteurFin)) {
					$compteurFin = $this->getChargesTable()->getChargeCompteursByID($charge->idCompteurFin);
					$charge->baseIndividuel = $compteurFin->valeurCompteur;
				}
				$odf->setVars('dateDebutPeriode', date('d/m/Y', strtotime($charge->dateDebutPeriode)), false, 'UTF8');
				$odf->setVars('dateFinPeriode', date('d/m/Y', strtotime($charge->dateFinPeriode)), false, 'UTF8');
				$segmentDetailCharge->setVars('nomCharge', $charge->nomCharge, false, 'UTF8');
				$segmentDetailCharge->setVars('montantReelGlobal', number_format($charge->montantReelGlobal, 2, '.', ' '), false, 'UTF8');
				$segmentDetailCharge->setVars('baseIndividuel', number_format($charge->baseIndividuel, 2, '.', ' '), false, 'UTF8');
				$segmentDetailCharge->setVars('baseTotal', number_format($charge->baseTotal, 2, '.', ' '), false, 'UTF8');
				$segmentDetailCharge->setVars('presence', $charge->presence, false, 'UTF8');
				$segmentDetailCharge->setVars('montantReel', number_format($charge->montantReel, 2, '.', ' '), false, 'UTF8');
				$segmentDetailCharge->setVars('montantProvision', number_format($charge->montantProvision, 2, '.', ' '), false, 'UTF8');
				$segmentDetailCharge->setVars('montantRepartition', number_format($charge->montantRepartition, 2, '.', ' '), false, 'UTF8');

				$segmentDetailCharge->merge();

				$totalMontantReel += $charge->montantReel;
				$totalMontantRepartition += $charge->montantRepartition;
			}
			$odf->mergeSegment($segmentDetailCharge);


			$odf->setVars('totalMontantReel', number_format($totalMontantReel, 2, '.', ' '), false, 'UTF8');
			$odf->setVars('totalMontantProvision', number_format($totalMontantProvision, 2, '.', ' '), false, 'UTF8');
			$odf->setVars('totalMontantRepartition', number_format($totalMontantRepartition, 2, '.', ' '), false, 'UTF8');

			$soldeReel = $totalMontantProvision - $totalMontantReel;
			$soldeProvision = $totalMontantReel - $totalMontantProvision;

			if ($soldeReel == 0) {
				$odf->setVars('soldeReel', '', false, 'UTF8');
				$odf->setVars('libelleSolde', "Vous n'avez rien à payer", false, 'UTF8');
			} elseif ($soldeReel > 0) {
				$odf->setVars('soldeReel', number_format($soldeReel, 2, '.', ' '), false, 'UTF8');
				$odf->setVars('libelleSolde', 'Solde en votre faveur', false, 'UTF8');
			} else {
				if (1) {
					## Cas standard : on veut afficher les soldes négatifs
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$odf->setVars('soldeReel', number_format(-$soldeReel, 2, '.', ' '), false, 'UTF8');
				} else {
					## Cas de Areli où on ne veut pas afficher les soldes négatifs
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					//$odf->setVars('soldeReel', number_format(-$soldeReel,2,'.',' '), false, 'UTF8');
					$odf->setVars('soldeReel', '0.00', false, 'UTF8');//Areli : il ne faut pas afficher ce solde si négatif
				}
				$odf->setVars('libelleSolde', 'Solde à payer', false, 'UTF8');
			}

			if ($soldeProvision > 0) {
				$odf->setVars('soldeProvision', number_format($soldeProvision, 2, '.', ' '), false, 'UTF8');
			} else {
				$odf->setVars('soldeProvision', '0.00', false, 'UTF8');
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] totalMontantReel=$totalMontantReel totalMontantProvision=$totalMontantProvision : count_charges=".count($charges)." count_chargesProv=".count($chargesProvRet)." count_chargesDetail=".count($chargesDetail));
		}
		## fin recup charges

		## Tableau des quotes-parts de charges
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		if ($resa && $resa->idLogement) {
			## Periode d'occupation
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($resa->dateArrivee && $resa->dateArrivee != "0000-00-00" && $tools->isValideDate($resa->dateArrivee)) {
				$odf->setVars("dateDebutOccupation", date('d/m/Y', strtotime($resa->dateArrivee)), false, 'UTF8');
			} else {
				$odf->setVars("dateDebutOccupation", "", false, 'UTF8');
			}
			if ($resa->dateDepart && $resa->dateDepart != "0000-00-00" && $tools->isValideDate($resa->dateDepart)) {
				$odf->setVars("dateFinOccupation", date('d/m/Y', strtotime($resa->dateDepart)), false, 'UTF8');
			} else {
				$odf->setVars("dateFinOccupation", "", false, 'UTF8');
			}

			$chargesQuotePart = $this->getChargesTable()->getTypesChargesDeLogement($resa->idLogement);
			#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire $loc[nom] quotePart=".json_encode($chargesQuotePart));
			$segmentQuotePart = $odf->setSegment('quotePartCharges');
			foreach ($chargesQuotePart as $charge) {
				$segmentQuotePart->setVars('nomCharge', $charge->nomCharge, false, 'UTF8');
				$segmentQuotePart->setVars('methodeCharge', $charge->nomMethode." (".$charge->codeMethode.")", false, 'UTF8');
				$segmentQuotePart->setVars('quotePart', number_format($charge->valeurTypeCharge, 2, '.', ' '), false, 'UTF8');

				$segmentQuotePart->merge();
			}
			$odf->mergeSegment($segmentQuotePart);
		}


		## Bredea
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				if ($resa->idPMS || $resa->numDossier || $resa->numResa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);
					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Dans le cas du modele MSEPS il faut aller lire des infos dans le PMS pour créer un nouveau RUM
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if($modele->code == "MSEPS") {
								$sepaData	= $this->getSEPATable()->getChampsDeResa($idResa, $resa->idLocataire);
								$newRumSEPA	= null;
								try {
									$newRumSEPA	= $this->pms->buildNewRumSEPA($resa);
									if ($newRumSEPA) {
										## Mise à jour de la BDD avec cette nouvelle valeur et dévalidation du mandat SEPA signé
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										$data['rumSEPA']		= $newRumSEPA;
										$data['mandatSEPA']		= null;
										$data['prelevementSEPA']	= 0;
										$where	= ['id' => $sepaData['id']];
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa updateRumSepa where=".json_encode($where)." data=".json_encode($data));
										$this->getSEPATable()->update($data, $where);

										## Mise à jour de CeriFoyer avec les infos de SEPA
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										$sepaData['rumSEPA']		= $newRumSEPA;
										$sepaData['mandatSEPA']		= null;
										$sepaData['prelevementSEPA']	= 0;
										$this->pms->updateSEPA($resa, $sepaData);

										## Utiliser le nouveau RUM
										## ~~~~~~~~~~~~~~~~~~~~~~~
										$odf->setVars('rumSEPA', $newRumSEPA, false, 'UTF8');
									}
								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa noFacture=$noFacture idModele=$idModele : CeriFoyer-ERROR-exception=".$ex->getMessage());
								}
								if (!$newRumSEPA) {
									return array('msg' => "Impossible de générer une Référence Unique du Mandat SEPA");
								}
							}

							## Compléter odf avec les infos de CeriFoyer
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							try {
								$this->pms->setVarsOdf($odf, $modeleCode, $resa, null, $odfVars);
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire fin-setVarsOdf");
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa noFacture=$noFacture idModele=$idModele : CeriFoyer-ERROR-exception=".$ex->getMessage());
							}
						}
					} else {
						if($modele->code == "MSEPS") {
							## Ce modèle ne peut pas se générer si le PMS n'est pas accessible
							return array('msg' => "Impossible d'accéder au PMS pour générer une RUM-SEPA");
						}
					}
				} else {
					if($modele->code == "MSEPS") {
						## Ce modèle ne peut pas se générer si le dossier n'est pas transféré
						return array('msg' => "Impossible de générer ce document si la demande n'est pas transférée au PMS");
					}
				}

				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();
					$bredeaData = array();

					$typre = $resa->typre ? $resa->typre : 'R';
					$cData = array('codeSite' => $codeSite, 'numResa' => $resa->numResa, 'numDossier' => $resa->numDossier, 'typre' => $typre, 'noFacture' => $noFacture, 'conf' => $conf);
					$bredeaData = $bredea->lireFacture($cData);

					$bredeaData['date_now'] = date('d/m/Y');

					//print_r($bredeaData);exit();


					$lignesPrestation = array();
					if (!empty($bredeaData['lignesPrestation'])) {
						$lignesPrestation = $bredeaData['lignesPrestation'];
						unset($bredeaData['lignesPrestation']);
					}


					$totalFacture = $totalPeriode = $total = $totalPeriode = 0;
					foreach ($bredeaData as $key => $value) {

						//on verifie la date
						$value  = $bredeaData[$key];
						if (is_array($value)) {
							continue;
						}
						if ($tools->isBredeaDate($value) && $key != 'numeroMandatSEPA') {
							$value = trim($value);
							if ($key == 'lig_perdeb' || $key == 'lig_perfin') {
								$value = $tools->getDateFromFormat($value);
							}
							$value = date('d/m/Y', strtotime($value));
						}
						if ($value === 0) {
							$value = "";
						}

						if ($key == "dossi_sexe") {
							$value = ($value == "F") ? 'Mme' : 'M';
						}
						$odf->setVars($key, utf8_encode($value), false, 'UTF8');
					}

					if ($bredeaData['dossi_sexe']) {
						$civ = (trim($bredeaData['dossi_sexe']) == "F") ? 'Mme' : 'M';
						$odf->setVars('dossi_sexe', utf8_encode($civ), false, 'UTF8');
					}
					if (!array_key_exists('cau_mteuro', $bredeaData) || empty($bredeaData['cau_mteuro'])) {
						//on cherche dans la table comptes
						$compteCau = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa, 'type' => 4))->current();
						if ($compteCau) {
							$odf->setVars('cau_mteuro', $compteCau->debit);
						} else {
							$odf->setVars('cau_mteuro', '0.00');
						}
						$odf->setVars('cau_date', '');
						$odf->setVars('cau_modreg', '');
					}

					$odf->setVars('date_now', date('d/m/Y'), false, 'UTF8');

					$odf->setVars('jvt_nofac', $bredeaData['jvt_nofac']);
					$odf->setVars('log_code', $bredeaData['log_code']);
					$odf->setVars('dossi_nodoss', str_repeat("0", 5 - (int)strlen($bredeaData['dossi_nodoss'])).$bredeaData['dossi_nodoss'], false, 'UTF8');
					$odf->setVars('dossi_nom', utf8_encode($bredeaData['dossi_nom']), false, 'UTF8');
					$odf->setVars('dossi_prenom', utf8_encode($bredeaData['dossi_prenom']), false, 'UTF8');
					$odf->setVars('dossi_ville', utf8_encode($bredeaData['dossi_ville']), false, 'UTF8');
					$odf->setVars('dossi_cp', utf8_encode($bredeaData['dossi_cp']), false, 'UTF8');
					$odf->setVars('dossi_adr1', utf8_encode($bredeaData['dossi_adr1']), false, 'UTF8');
					$odf->setVars('dossi_adr2', utf8_encode($bredeaData['dossi_adr2']), false, 'UTF8');

					$odf->setVars('si_ville', utf8_encode($bredeaData['si_ville']), false, 'UTF8');
					$odf->setVars('si_nom', utf8_encode($bredeaData['si_nom']), false, 'UTF8');
					$odf->setVars('log_ville', utf8_encode($bredeaData['log_ville']), false, 'UTF8');
					$odf->setVars('log_adr1', utf8_encode($bredeaData['log_adr1']), false, 'UTF8');
					$odf->setVars('log_adr2', utf8_encode($bredeaData['log_adr2']), false, 'UTF8');
					$odf->setVars('log_batiment', utf8_encode($bredeaData['log_batiment']), false, 'UTF8');

					if ($idModele == 2) {
						$odf->setVars('drecu_no', $bredeaData['drecu_no']);
						$odf->setVars('drecu_nom', utf8_encode($bredeaData['drecu_nom']), false, 'UTF8');
						$odf->setVars('drecu_modreg', utf8_encode($bredeaData['drecu_modreg']), false, 'UTF8');
						$odf->setVars('drecu_detlib_1', utf8_encode($bredeaData['drecu_detlib_1']), false, 'UTF8');
						$odf->setVars('drecu_detlib_2', utf8_encode($bredeaData['drecu_detlib_2']), false, 'UTF8');
						$odf->setVars('drecu_detlib_3', utf8_encode($bredeaData['drecu_detlib_3']), false, 'UTF8');
					}

					$bfac1 = trim($bredeaData['csi_bfac1']);
					$bfac2 = trim($bredeaData['csi_bfac2']);
					if (!$bfac1) {
						$bfac1 = trim($bredeaData['snomsoc'])." - ".trim($bredeaData['sadre1'])." ".trim($bredeaData['sadre2'])." - ".trim($bredeaData['spostal'])." ".trim($bredeaData['sville']);
						$odf->setVars('csi_bfac1', utf8_encode($bfac1), false, 'UTF8');
					}
					if (!$bfac2) {
						$bfac2 = "Siret : ".trim($bredeaData['siret'])." - APE : ".trim($bredeaData['sape'])." - Intracom : ".trim($bredeaData['scee']);
						$odf->setVars('csi_bfac2', utf8_encode($bfac2), false, 'UTF8');
					}

					if ($idModele == 1 || $idModele == 5 || $idModele == 4) {
						if (trim($bredeaData['lig_perdeb']) != "" && trim($bredeaData['lig_perfin']) != "" && trim($bredeaData['lig_perdeb']) != "0" && trim($bredeaData['lig_perfin']) != "0") {
							$lig_perdeb = $tools->getDateFromFormat($bredeaData['lig_perdeb']);
							//$odf->setVars('lig_perdeb',date('d/m/Y',strtotime($lig_perdeb)));

							$lig_perfin = $tools->getDateFromFormat($bredeaData['lig_perfin']);
							//$odf->setVars('lig_perfin',date('d/m/Y',strtotime($lig_perfin)));

							$segment = $odf->setSegment('lignePeriode');

							$segment->setVars('lig_perdeb', date('d/m/Y', strtotime($lig_perdeb)), false, 'UTF8');
							$segment->setVars('lig_perfin', date('d/m/Y', strtotime($lig_perfin)), false, 'UTF8');

							$segment->merge();

							$odf->mergeSegment($segment);
						} else {
							$segment = $odf->setSegment('lignePeriode');
							$segment->merge(true);
							$odf->mergeSegment($segment);
						}
					}

					$soldeFacture = 0;
					$totalRegle = 0;

					if ($idModele == 4) {
						//quittance

						if (!empty($bredeaData['reglements'])) {
							$reglements = $bredeaData['reglements'];

							foreach ($reglements as $reg) {
								$segmentR = $odf->setSegment('ligneReglement');

								$segmentR->setVars('reg_date', date('d/m/Y', strtotime($reg['reg_date'])));
								$segmentR->setVars("reg_modreg", utf8_encode($reg['reg_modreg']), false, 'UTF8');
								$segmentR->setVars("reg_mteuro", str_replace('.', ',', $reg['reg_mteuro']));

								$segmentR->merge();
								$odf->setVars('date_reglement', date('d/m/Y', strtotime($reg['reg_date'])));
								$odf->mergeSegment($segmentR);
							}
						} else {
							$segmentR = $odf->setSegment('ligneReglement');
							$segmentR->merge(true);
							$odf->mergeSegment($segmentR);
						}
					}

					## prestations preparation de facture
					$odfVarsAndSegement = $odf->getVarsAndSegments();
					foreach($odfVarsAndSegement as $odfVar => $nbr) {
						if(substr($odfVar, 0, 6) == '{CALC_') {
							$retFormule = $tools->calculerFormuleModuleDocs($odfVar, $bredeaData);
							$odfVar = substr($odfVar, 1, strlen($odfVar));//on enlève le premier {}
							$odfVar = substr($odfVar, 0, -1);//on enlève le dernier }
							$odf->setVars($odfVar, str_replace('.', ',', $retFormule));
						}
					}
					if (in_array('BEGIN_lignePrestationPrep', $odfVarsAndSegement) || array_key_exists('BEGIN_lignePrestationPrep', $odfVarsAndSegement)) {
						if (!empty($bredeaData['prestationsPrepFacture'])) {
							$prestationsPrep = $bredeaData['prestationsPrepFacture'];
							$segmentPPF = $odf->setSegment('lignePrestationPrep');
							foreach ($prestationsPrep as $ppf) {
								$segmentPPF->setVars("pfa_lib", utf8_encode($ppf['pfa_lib']), false, 'UTF8');
								$segmentPPF->setVars("pfa_mteuro", str_replace('.', ',', $ppf['pfa_mteuro']));
								$segmentPPF->setVars("pfa_prest", utf8_encode($ppf['pfa_prest']), false, 'UTF8');
								$segmentPPF->setVars("pfa_qte", str_replace('.', ',', $ppf['pfa_qte']));
								$segmentPPF->setVars("pfa_ttc", str_replace('.', ',', $ppf['pfa_ttc']));
								$segmentPPF->setVars("pfa_mt", str_replace('.', ',', $ppf['pfa_mt']));
								$segmentPPF->setVars("pfa_ligne", $ppf['pfa_ligne']);
								if(!empty($ppf['prest'])) {
									$segmentPPF->setVars("pre_tva", str_replace('.', ',', $ppf['prest']['pre_tva']));
								} else {
									$segmentPPF->setVars("pre_tva", '');
								}
								$segmentPPF->merge();
							}
							$odf->mergeSegment($segmentPPF);
						} else {
							$segmentPPF = $odf->setSegment('lignePrestationPrep');
							$segmentPPF->merge(true);
							$odf->mergeSegment($segmentPPF);
						}
					}

					## prestations site
					if (in_array('BEGIN_lignePrestationSite', $odfVarsAndSegement) || array_key_exists('BEGIN_lignePrestationSite', $odfVarsAndSegement)) {
						if (!empty($bredeaData['prestationsSite'])) {
							$prestationsSite = $bredeaData['prestationsSite'];
							$segmentPPF = $odf->setSegment('lignePrestationSite');
							foreach ($prestationsSite as $ppf) {
								$segmentPPF->setVars("pre_lib", utf8_encode($ppf['pre_lib']), false, 'UTF8');
								$segmentPPF->setVars("pre_mteuro", str_replace('.', ',', $ppf['pre_mteuro']));
								$segmentPPF->setVars("pre_code", utf8_encode($ppf['pre_code']), false, 'UTF8');
								$segmentPPF->setVars("pre_qte", str_replace('.', ',', $ppf['pre_qte']));
								$segmentPPF->setVars("pre_ttc", str_replace('.', ',', $ppf['pre_ttc']));
								$segmentPPF->setVars("pre_mt", str_replace('.', ',', $ppf['pre_mt']));
								$segmentPPF->setVars("pre_tva", str_replace('.', ',', $ppf['pre_tva']));

								$segmentPPF->merge();
							}
							$odf->mergeSegment($segmentPPF);
						} else {
							$segmentPPF = $odf->setSegment('lignePrestationPrep');
							$segmentPPF->merge(true);
							$odf->mergeSegment($segmentPPF);
						}
					}

					## solde antérieur dû ou en faveur
					if (in_array('BEGIN_ligneSoldeAnetrieurD', $odfVarsAndSegement) || array_key_exists('BEGIN_ligneSoldeAnetrieurD', $odfVarsAndSegement)) {
						$segmentSAD = $odf->setSegment('ligneSoldeAnetrieurD');
						if(array_key_exists('solde_anterieur', $bredeaData) && $bredeaData['solde_anterieur'] >= 0) {
							$segmentSAD->setVars("solde_anterieur", str_replace('.', ',', $bredeaData['solde_anterieur']));
							$segmentSAD->merge();
						} else {
							$segmentSAD->merge(true);
						}
						$odf->mergeSegment($segmentSAD);
					}

					if (in_array('BEGIN_ligneSoldeAnetrieurC', $odfVarsAndSegement) || array_key_exists('BEGIN_ligneSoldeAnetrieurC', $odfVarsAndSegement)) {
						$segmentSAC = $odf->setSegment('ligneSoldeAnetrieurC');
						if($bredeaData['solde_anterieur'] && $bredeaData['solde_anterieur'] < 0) {
							$segmentSAC->setVars("solde_anterieur", str_replace('.', ',', $bredeaData['solde_anterieur']));
							$segmentSAC->merge();
						} else {
							$segmentSAC->merge(true);
						}
						$odf->mergeSegment($segmentSAC);
					}

					##Caution : montant restant à réglé
					$soldeCache = $this->getTableObjet('pmsCache')->select(array('idReservation'	=> $idResa, 'typeCache' => 'solde'))->current();
					$soldeCaution = 0;
					if($soldeCache && $soldeCache->valeur2) {
						//$soldeCaution = $soldeCache->valeur2 - $soldeCache->valeur;
						$soldeCaution = $soldeCache->valeur - $soldeCache->valeur2;
					}
					$odf->setVars('soldeCaution', str_replace('.', ',', $soldeCaution));
					$dossi_mtverseeuro = sprintf("%.2f", $bredeaData['dossi_mtverseeuro']);
					$odf->setVars('dossi_mtverseeuro', str_replace('.', ',', $dossi_mtverseeuro));
					$odf->setVars('dossi_mtverseeuro', str_replace('.', ',', $bredeaData['dossi_mtverseeuro']));

					$resteARegler = 0;
					if($bredeaData['dossi_mtverseeuro']) {
						$dossi_mtverseeuro = sprintf("%.2f", $bredeaData['dossi_mtverseeuro']);
						$dossi_mtverseeuro = (float)$dossi_mtverseeuro;

						$resteARegler = $dossi_mtverseeuro - $soldeCaution;

						$resteARegler = sprintf("%.2f", $resteARegler);
						$resteARegler = (float)$resteARegler;
						$resteARegler = sprintf("%.2f", $resteARegler);
					}
					$odf->setVars('resteARegler', str_replace('.', ',', $resteARegler));

					## Ecritures précédente
					if (in_array('BEGIN_ecrituresPrecedentes', $odfVarsAndSegement) || array_key_exists('BEGIN_ecrituresPrecedentes', $odfVarsAndSegement)) {
						$segmentEP = $odf->setSegment('ecrituresPrecedentes');
						$ecrituresPrecedentes = array_key_exists('ecrituresPrecedentes', $bredeaData) ? $bredeaData['ecrituresPrecedentes'] : array();
						if(!empty($ecrituresPrecedentes)) {
							foreach($ecrituresPrecedentes as $ep) {
								//date le libéllé et le montant
								$segmentEP->setVars("dateEP", date('d/m/Y', strtotime($ep['hfa_date'])));
								$segmentEP->setVars("libelleEP", utf8_encode($ep['hfa_lib']), false, 'UTF8');
								$segmentEP->setVars("montantEP", str_replace('.', ',', $ep['hfa_mteuro']));
								$segmentEP->setVars("modregEP", $ep['hfa_modreg']);
								$segmentEP->merge();
							}
						} else {
							$segmentEP->merge(true);
						}
						$odf->mergeSegment($segmentEP);
					}

					//caution
					if (!empty($bredeaData['cau_mteuro'])) {
						$total += $bredeaData['cau_mteuro'];
					}
					//Prets
					$totalPrets = 0;
					if (!empty($bredeaData['prets'])) {
						foreach ($bredeaData['prets'] as $pRow) {
							$totalPrets += $pRow['pret_mteuro'];
						}
						$total += $totalPrets;
						$odf->setVars('pret_mteuro', $totalPrets);
					} else {
						$odf->setVars('pret_mteuro', "");
					}
					//Epargne
					$totalEpargne = 0;
					if (!empty($bredeaData['epargne'])) {
						foreach ($bredeaData['epargne'] as $pRow) {
							$totalEpargne += $pRow['epa_mteuro'];
						}
						$total += $totalEpargne;
						$odf->setVars('epa_mteuro', $totalPrets);
					} else {
						$odf->setVars('epa_mteuro', "");
					}

					if (!empty($lignesPrestation) && ($idModele == 1 || $idModele == 5 || $idModele == 4)) {
						## lignes Prestation
						//if($idModele == 1){
						$segment = $odf->setSegment('lignePrestation');
						$segment2 = $odf->setSegment('lignePrestation2');
						foreach ($lignesPrestation as $ligne) {
							//$segment->element_texte("Lorem ipsum...");

							if (trim($ligne['lig_prest']) == "ZZZZ") {
								$segment2->setVars("lignePrestationDesignation2", utf8_encode($ligne['lig_libprest']), false, 'UTF8');
								$segment2->setVars("lignePrestationMontant2", str_replace('.', ',', sprintf("%.2f", $ligne['lig_mteuro'] * (-1))));
								$totalPeriode2 += $ligne['lig_mteuro'] * (-1);
								$segment2->merge();
							} else {
								$segment->setVars("lignePrestationDesignation", utf8_encode($ligne['lig_libprest']), false, 'UTF8');
								$segment->setVars("lignePrestationQte", $ligne['lig_qte']);
								if (trim($ligne['lig_uniteuro']) == "0") {
									$segment->setVars("lignePrestationPrixUnitaire", str_replace('.', ',', $ligne['lig_pueuro']));
								} else {
									$segment->setVars("lignePrestationPrixUnitaire", str_replace('.', ',', $ligne['lig_uniteuro']));
								}
								$segment->setVars("lignePrestationMontant", str_replace('.', ',', $ligne['lig_mteuro']));
								$segment->setVars("lignePrestationTVA", str_replace('.', ',', $ligne['lig_tva']));
								$segment->setVars("lignePrestationPrixHT", str_replace('.', ',', $ligne['lig_hteuro']));
								$segment->setVars("lignePrestationTauxTVA", str_replace('.', ',', $ligne['lig_txtva']));
								$segment->setVars("lignePrestationMontantTVA", str_replace('.', ',', $ligne['lig_mttvaeuro']));
								$totalPeriode += $ligne['lig_mteuro'];
								$segment->merge();
							}
						}
						//}
						/*elseif($idModele == 5){
							$segment = $odf->setSegment('lignePrestation');
							foreach($lignesPrestation as $ligne){
								//$segment->element_texte("Lorem ipsum...");
								if(trim($ligne['lig_prest'])=="ZZZZ"){
									$segment->setVars("lignePrestationDesignation", utf8_encode($ligne['lig_libprest']),false,'UTF8');
									$segment->setVars("lignePrestationMontant", str_replace('.',',',$ligne['lig_mteuro']*(-1)));
									$totalPeriode += $ligne['lig_mteuro']*(-1);
									$segment->merge();
								}else{
									$segment->setVars("lignePrestationDesignation", utf8_encode($ligne['lig_libprest']),false,'UTF8');
									$segment->setVars("lignePrestationQte", $ligne['lig_qte']);
									$segment->setVars("lignePrestationPrixUnitaire", str_replace('.',',',$ligne['lig_pueuro']));
									$segment->setVars("lignePrestationMontant", str_replace('.',',',$ligne['lig_mteuro']));
									$totalPeriode += $ligne['lig_mteuro'];
									$segment->merge();
								}


							}

							$odf->mergeSegment($segment);
						}*/

						$odf->mergeSegment($segment);
						$odf->mergeSegment($segment2);

						$totalFacture = $totalPeriode + $totalPeriode2;
						$total += $totalFacture;
						$odf->setVars('totalPeriode', str_replace('.', ',', $totalPeriode));
						$odf->setVars('totalFacture', str_replace('.', ',', $totalFacture));

						$montantPrestationAVerser = $totalFacture < 0 ? abs($totalFacture) : 0;
						$odf->setVars('montantPrestationAVerser', str_replace('.', ',', $montantPrestationAVerser));

						$total = $totalFacture;
						if ($bredeaData['solde_anterieur']) {
							$total += $bredeaData['solde_anterieur'];
						} else {
							$odf->setVars('solde_anterieur', '0,00');
						}

						## montant du ou en votre faveur
						if (in_array('BEGIN_ligneTotalD', $odfVarsAndSegement) || array_key_exists('BEGIN_ligneTotalD', $odfVarsAndSegement)) {
							$segmentSD = $odf->setSegment('ligneTotalD');
							if($total >= 0) {
								$segmentSD->merge();
							} else {
								$segmentSD->merge(true);
							}
							$odf->mergeSegment($segmentSD);
						}

						## montant du ou en votre faveur
						if (in_array('BEGIN_ligneTotalC', $odfVarsAndSegement) || array_key_exists('BEGIN_ligneTotalC', $odfVarsAndSegement)) {
							$segmentSC = $odf->setSegment('ligneTotalC');
							if($total < 0) {
								$segmentSC->merge();
							} else {
								$segmentSC->merge(true);
							}
							$odf->mergeSegment($segmentSC);
						}

						$odf->setVars('total', str_replace('.', ',', $total));
					}//end if lignes prestation
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire exception=".$ex->getMessage());
				//echo $ex->getMessage();exit();
			}
		}
		## Fin Bredea

		//$odfVarsAndSegement = $odf->getVarsAndSegments();


		//$odf->setVars('nom', 'Mon titre dynamique');

		//echo $outputFolder.$modeleName;

		// Ajouter une image:
		//$odf->setImage('image', 'web-d.jpg');

		//$odf->exportAsAttachedFile("Exemple ODTPHP.odt");
		//echo $outputFolder.$modeleName;exit();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire avant saveToDisk1($outputFolder$modeleName)");
		$odf->saveToDisk($outputFolder.$modeleName);
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire apres saveToDisk1($outputFolder$modeleName)");

		if (file_exists($outputFolder.$modeleName)) {
			$odfCreer = new odf($outputFolder.$modeleName, array('ZIP_PROXY' => 'PhpZipProxy'));
			$odfVarsAndSegement = $odfCreer->getVarsAndSegments();
			//print_r($odfVarsAndSegement);exit();
			if (!empty($odfVarsAndSegement)) {
				foreach ($odfVarsAndSegement as $odfVS => $nbrVars) {
					if (substr($odfVS, 0, 5) == 'BEGIN') {
						//segement
						$segName = str_replace('BEGIN_', '', $odfVS);
						$segment = $odf->setSegment($segName);
						$segment->merge(true);
						$odf->mergeSegment($segment);
					} elseif (substr($odfVS, 0, 1) == '{') {
						//var
						$varName = str_replace('{', '', $odfVS);
						$varName = str_replace('}', '', $varName);
						$odf->setVars($varName, '');
					}
				}
				//on re genere le fichier
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire avant saveToDisk2($outputFolder$modeleName)");
				$odf->saveToDisk($outputFolder.$modeleName);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire apres saveToDisk2($outputFolder$modeleName)");
			}
		}
		//exit();

		#### WAIT ####

		$originFilePath = $outputFolder.$modeleName;
		$outputDirPath  = $outputFolder;

		$fichier = pathinfo($modeleName, PATHINFO_FILENAME);

		//on supprimer la version anteriere
		if (file_exists($outputDirPath.$fichier.'.pdf')) {
			$this->deleteFile($outputDirPath.$fichier.'.pdf');
		}

		if (file_exists($locataireFolder.$pdfName.'.pdf')) {
			$this->deleteFile($locataireFolder.$pdfName.'.pdf');
		}

		try {
			if ($_SERVER['REMOTE_ADDR'] == '82.64.12.217') {
				$odt2pdfCmd     = "/usr/bin/libreoffice --writer -env:UserInstallation=file:///tmp/test --headless --convert-to pdf --outdir $outputDirPath $originFilePath";
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire avant odt2pdfCmd=$odt2pdfCmd");
				$cmdLastLine    = exec($odt2pdfCmd, $cmdOutput, $cmdResultCode);
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire apres odt2pdfCmd=$odt2pdfCmd resultCode=$cmdResultCode lastLine=".json_encode($cmdLastLine)." output=".json_encode($cmdOutput));

			} else {
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire avant unoconv -f pdf $originFilePath");
				$cmdOutput	= shell_exec("unoconv -f pdf $originFilePath");
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire apres unoconv -f pdf $originFilePath cmdOutput=".json_encode($cmdOutput));
				// Unoconv::convertToPdf($originFilePath, $outputDirPath);
			}
		} catch (\Exception $ex) {
			echo $ex->getMessage();
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire exception=".$ex->getMessage());
			exit();
		}

		//$fichier = pathinfo($modeleName, PATHINFO_FILENAME);
		// if($typeOutput!="pdf" && $typeOutput!="odt"){
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire outputDirPath=$outputDirPath fichier=$fichier");
		if (file_exists($outputDirPath.$fichier.'.pdf')) {
			copy($outputDirPath.$fichier.'.pdf', $locataireFolder.$pdfName.'.pdf');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire copie de $outputDirPath$fichier.pdf vers $locataireFolder$pdfName.pdf");
		} else {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire pas de $outputDirPath$fichier.pdf");
		}

		//exit();

		$name = pathinfo($modeleName, PATHINFO_FILENAME);
		$name .= ".pdf";

		$urlGeneratedFile .= $pdfName.'.pdf';
		if ($urlReturn == "ABSOLU") {
			$url = $locataireFolder.$pdfName.'.pdf';
			return $url;
			// return getcwd()."/public/docs".explode('docs',$urlGeneratedFile)[1];
		}

		if ($typeOutput == "pdf") {
			$name = pathinfo($modeleName, PATHINFO_FILENAME);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire idResidence=$idResidence typeOutput=$typeOutput url=$name.pdf");
			return $name.'.pdf';
		} elseif ($typeOutput == "odt") {
			if ($conf->formatExportMD == "docx") {
				//on supprime avant de cree si existe
				$this->deleteFile($outputDirPath.$fichier.'.docx');
				Unoconv::convert($originFilePath, $outputDirPath, 'docx');// ajouté, modif 16-05
				$name = pathinfo($modeleName, PATHINFO_FILENAME);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire idResidence=$idResidence typeOutput=$typeOutput url=$name.docx");
				return $name.'.docx'; //modif 16-05, avant : .odt
			} else {
				$name = pathinfo($modeleName, PATHINFO_FILENAME);
				return $name.'.odt';
			}
		}

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire idResidence=$idResidence urlReturn=$urlReturn typeOutput=$typeOutput urlGeneratedFile=$urlGeneratedFile");
		return $urlGeneratedFile;



		#### WAIT ####
		//header('Content-type: application/pdf');
		// header('Content-Disposition: attachment; filename="'.$pdfName.'.pdf'.'"');
		//readfile($locataireFolder.$pdfName.'.pdf');
	}
	private function saveGeneratedDoc($data)
	{

		$idCategorie = $data['idCategorie'];
		$lienDoc = $data['lienDoc'];
		$mode = $data['mode'] ? $data['mode'] : false;
		$dpOrSuivi = $data['idDpOrSuivi'] ? $data['idDpOrSuivi'] : false;
		$idResa = $data['idResa'] ? $data['idResa'] : false;
		$edir = explode("/", $lienDoc);
		$isDpSuivis = false;
		if ($mode == 'suivis') {
			$suiviRow = $this->getTableObjet('suivis')->select(array('id' => $dpOrSuivi))->current();
			if ($suiviRow->idDp != "") {
				$idDpOrResa = $suiviRow->idDp;
				$dpRow = $this->getTableObjet('domiciliations')->select(array('id' => $idDpOrResa))->current();
				// $locataireRow = $this->getTableObjet('locataires')
				// ->select(array('id' => $resaRow->idLocataire))->current();
				$idLocataire = $dpRow->idLocataire;
				$isDpSuivis = true;
			} else {
				$idDpOrResa = $suiviRow->idResa;
				$resaRow = $this->getTableObjet('reservations')->select(array('id' => $idDpOrResa))->current();
				// $locataireRow = $this->getTableObjet('locataires')->select(array('id' => $dpRow->idLocataire))->current();
				$idLocataire = $resaRow->idLocataire;
			}
		} else {
			$idLocataire = $edir[8];
		}
		$docName = $edir[count($edir) - 1];
		// $docName = str_replace(".pdf", '', $docName);
		// array_pop($edir);
		// $edir = implode("/", $edir);
		// 	on copie le fichier
		if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
			mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
		}
		if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/")) {
			mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/");
		}
		$dirCp = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie;
		if (!is_dir($dirCp)) {
			mkdir($dirCp);
		}
		$folder = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie.'/';
		$copied = copy($lienDoc, $folder.$docName);
		$this->deleteFile($lienDoc);
		//on save le doc
		$doc = new Document();
		$doc->idCategorie = $idCategorie;
		$doc->nom = $docName;
		$doc->doc64 = "";
		$doc->libelle = date('d_m_Y_H_i') . "_" . $docName;
		$doc->etatResa = array(2, 3, 7, 6, 1, 9);
		$doc->isResident = 1;
		$doc->typeDoc = 'statique';
		$doc->idModele = null;
		$docId = $this->getDocumentTable()->saveDocument($doc);
		if ($mode == "dp" || ($mode == "suivis") && $isDpSuivis) {
			$docDp = $this->getTableObjet('document_dp')
			->select(array('idDocument' => $docId, 'idDp' => $idDpOrResa))->current();
			if (!$docDp) {
				$this->getTableObjet('document_dp')
				->insert(array('idDocument' => $docId, 'idDp' => $idDpOrResa));
			}
		} else {
			$docResa = $this->getTableObjet('document_locataire')
			->select(array('idDocument' => $docId, 'idReservation' => $idResa))->current();
			if (!$docResa) {
				$this->getTableObjet('document_locataire')
				->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
			}
		}
		return $docName;
	}

	public function modelesDocumentsEventAction($dataLien = false)
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idCategorie = $request->getPost('idCategorie');
			$lienDoc = $dataLien ? $datalien : $$request->getPost('lienDoc');

			// echo "<pre>";
			// var_dump($idCategorie);
			// var_dump($lienDoc);
			// echo "</pre>";
			// die();

			foreach ($lienDoc as $key => $value) {
				$edir = explode("/", $value['lien']);
				$isDpSuivis = false;

				$idDpOrResa = $value['id'];
				if ($value['mode'] == 'suivis') {
					$suiviRow = $this->getTableObjet('suivis')->select(array('id' => $value['idSuivis']))->current();
					if ($suiviRow->idDp != "") {
						$idDpOrResa = $suiviRow->idDp;
						$dpRow = $this->getTableObjet('domiciliations')->select(array('id' => $idDpOrResa))->current();
						// $locataireRow = $this->getTableObjet('locataires')
						// ->select(array('id' => $resaRow->idLocataire))->current();
						$idLocataire = $dpRow->idLocataire;
						$isDpSuivis = true;
					} else {
						$idDpOrResa = $suiviRow->idResa;
						$resaRow = $this->getTableObjet('reservations')->select(array('id' => $idDpOrResa))->current();
						// $locataireRow = $this->getTableObjet('locataires')->select(array('id' => $dpRow->idLocataire))->current();
						$idLocataire = $resaRow->idLocataire;
					}
				} else {
					$idLocataire = $edir[8];
				}

				$docName = $edir[count($edir) - 1];
				// array_pop($edir);
				// $edir = implode("/", $edir);

				// 	on copie le fichier
				if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire)) {
					mkdir(getcwd()."/public/docs/locataires/".$idLocataire);
				}

				if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/")) {
					mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/");
				}


				$dirCp = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie;
				if (!is_dir($dirCp)) {
					mkdir($dirCp);
				}


				$folder = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie.'/';
				$copied = copy($value['lien'], $folder.$docName);

				//on save le doc
				$doc = new Document();
				$doc->idCategorie = $idCategorie;
				$doc->nom = $docName;
				$doc->doc64 = "";
				$doc->libelle = date('d_m_Y_H_i') . "_" . $docName;
				$doc->etatResa = array(2, 3, 7, 6, 1, 9);
				$doc->isResident = 1;
				$doc->typeDoc = 'statique';
				$doc->idModele = null;
				$docId = $this->getDocumentTable()->saveDocument($doc);

				if ($value['mode'] == "dp" || ($value['mode'] == "suivis") && $isDpSuivis) {
					$docDp = $this->getTableObjet('document_dp')
					->select(array('idDocument' => $docId, 'idDp' => $idDpOrResa))->current();
					if (!$docDp) {
						$this->getTableObjet('document_dp')
						->insert(array('idDocument' => $docId, 'idDp' => $idDpOrResa));
					}
				} else {
					$docResa = $this->getTableObjet('document_locataire')
					->select(array('idDocument' => $docId, 'idReservation' => $idDpOrResa))->current();
					if (!$docResa) {
						$this->getTableObjet('document_locataire')
						->insert(array('idDocument' => $docId, 'idReservation' => $idDpOrResa));
					}
				}


				$value['idCategorie'] = $idCategorie;
				$value['docName'] = $docName;
				$value['docId'] = $docId;

				$log = new Logs();
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->idLocataire = $idLocataire;
				$log->operation = "BO : Générer le modèle de document (suite à un event action)";
				$log->dataBefore = "";
				$log->dataAfter = $value;
				$log->tableName = "document_dp/document_locataire";

				$this->getLogsTable()->saveLogs($log);
			}

			return new JsonModel(array('success' => true));
		}
	}
	private function withManuscriteSignature($post)
	{
		return new JsonModel(['success' => true, 'post' => $post]);
	}
	public function modelesdocumentsAction()
	{
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			$conf = $this->getConfigurationTable()->getConfig(1);

			$idModele = $request->getPost('idModeleDocument');
			$idResa = $request->getPost('idResaMD', 0);
			$idLocataire = (int) $this->params()->fromRoute('id', 0);
			$type = $request->getPost('type');//pdf,odt,web
			$lang = $request->getPost('lang');
			$idDp = $request->getPost('idDp', 0);
			$idCategorie = $request->getPost('idCategorie', null);
			$urlReturn = $request->getPost('urlReturn', false);
			$postData = array();
			if(isset($_POST['rib_rib'])){
				$postData = (array) $request->getPost();
				unset($postData['idModeleDocument']);
				unset($postData['idResaMD']);
				unset($postData['id']);
				unset($postData['idDp']);
				unset($postData['idCategorie']);
				unset($postData['urlReturn']);
				unset($postData['lang']);
				unset($postData['type']);
			}

			if (!$type) {
				$type = "pdf";
			}
			$options = array('type' => $type);
			if($urlReturn) {
				$options['urlReturn'] = $urlReturn;
			}
			if ($lang) {
				$options['lang'] = $lang;
			}
			$options['mode'] = $mode;
			if(!empty($postData)){
				$options['postData'] = $postData;
			}

			if ($idDp) {
				$options['mode'] = 'dp';
				$urlGeneratedFile = $this->genererModeleDocument($idDp, "", $idModele, $options);
			} elseif ($idResa) {
				$urlGeneratedFile = $this->genererModeleDocument($idResa, "", $idModele, $options);
			}

			## $urlGeneratedFile	= ['msg' => "AK erreur provoquée pour tests"];
			if(is_array($urlGeneratedFile)) {
				$view = new JsonModel(array(
						'success' => false,
						'idLocataire' => $idLocataire,
						'idReservation' => $idResa,
						'urlGeneratedFile' => '',
						'htmlOP' => '',
						'msg' => !empty($urlGeneratedFile['msg']) ? $urlGeneratedFile['msg'] : 'Une erreur est survenue',

				));

				$view->setTerminal(true);
				return $view;
			}
			$htmlOutput = "";

			if ($urlGeneratedFile && $idCategorie) {
				if($urlReturn == 'ABSOLU') {

					$docName = $this->saveGeneratedDoc(['idCategorie' => $idCategorie,
														'lienDoc' => $urlGeneratedFile,
														'mode' => $mode,
														'idDpOrSuivi' => $idDp,
														'idResa' => $idResa]);
				} else {


					//on stock le fichier dans la cat
					$modele = $this->getTableObjet('type_modeles_docs')->select(array('id' => $idModele))->current();
					$nomDoc = $modele->nom;
					$etatResa = array(2, 3, 7, 6, 1, 9);
					$libelle = "";

					//on copie le fichier
					if (!is_dir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie)) {
						mkdir(getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie);
					}
					$folder = getcwd()."/public/docs/locataires/".$idLocataire."/uploads/".$idCategorie.'/';
					$outputDirPath = getcwd()."/public/docs/modeles/output/";
					$fichier = $urlGeneratedFile;

					copy($outputDirPath.$fichier, $folder.$urlGeneratedFile);
					$docName = pathinfo($fichier, PATHINFO_FILENAME).'.pdf';
				}
				//on save le doc
				$doc = new Document();
				$doc->idCategorie = $idCategorie;
				$doc->nom = $docName;
				$doc->doc64 = "";
				$doc->libelle = $nomDoc;
				$doc->etatResa = $etatResa;
				$doc->isResident = 1;
				$doc->typeDoc = 'statique';
				$doc->idModele = null;
				$docId = $this->getDocumentTable()->saveDocument($doc);
				if ($idResa) {
					$docResa = $this->getTableObjet('document_locataire')->select(array('idDocument' => $docId, 'idReservation' => $idResa))->current();
					if (!$docResa) {
						$this->getTableObjet('document_locataire')->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
					}
				} elseif ($idDp) {
					$docDp = $this->getTableObjet('document_dp')->select(array('idDocument' => $docId, 'idDp' => $idDp))->current();
					if (!$docDp) {
						$this->getTableObjet('document_dp')->insert(array('idDocument' => $docId, 'idDp' => $idDp));
					}
				}
				$loc = $this->getLocataireTable()->getLocataire($idLocataire);
				$htmlOutput = mb_convert_encoding($this->loaddocumentsTab($loc, $idResa, false, $idDp), 'UTF-8', 'UTF-8');
			}

			$view = new JsonModel(array(
						'success' => true,
						'idLocataire' => $idLocataire,
						'idReservation' => $idResa,
						'urlGeneratedFile' => $urlGeneratedFile,
						'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function ajouterresaAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$form = new LocataireForm();
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idLocataire = $request->getPost('id');
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
			$locOld = $this->getLocatairesTable()->getLocataire($idLocataire);
			if ($loc) {
				$form->bind($loc);
			} else {
				$loc = new Locataires();
			}
			$form->setInputFilter($loc->getInputFilter());

			$form->setData($request->getPost());

			$loc->exchangeArray($request->getPost());

			$log = new Logs();

			if ($idLocataire) {
				$this->getLocatairesTable()->majLocataire($loc);
				$log->operation = "BO : Update usager : ".$loc->nom.' '.$loc->prenom;
			} else {
				$idLocataire = $this->getLocatairesTable()->saveLocataire($loc);
				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				$form->bind($loc);
				$log->operation = "BO : Ajout nouvel usager : ".$loc->nom.' '.$loc->prenom;
			}


			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->dataBefore = array();
			$log->dataAfter = $loc;
			$log->idLocataire = $loc->id;
			$log->tableName = "Locataires";

			$this->getLogsTable()->saveLogs($log);

			$tablePile = new Tables('pile', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$dansLaPile = $tablePile->getTable()->select(array('idLocataire' => $idLocataire))->current();

			if (!$dansLaPile) {
				//ajout dans pile
				$pile = new Pile();
				$data['idReservation'] = null;
				$data['idLocataire'] = $idLocataire;
				$data['flag'] = "reservation";
				$pile->exchangeArray($data);
				$this->getPileTable()->empile($pile);
			}

			## ajout resa
			$idLogement = $request->getPost('idLogement');
			$logement = $this->getLogementTable()->getLogement($idLogement);
			$resa = new Resa();
			$resa->id = 0;
			$resa->idLogement = $request->getPost('idLogement');
			$resa->dateArrivee = $request->getPost('dateArrivee');
			$resa->dateDepart = $request->getPost('dateDepart');
			$resa->dateDemandeReservation = date('d-m-Y H:i:s');
			$resa->idLocataire = $idLocataire;
			$resa->idProgramme = $loc->idProgramme;
			$resa->idSousProgramme = $loc->idSousProgramme;
			$resa->idTypeLogement = $logement->idTypeLogement;
			$resa->typeLogement1 = $logement->idTypeLogement;
			$resa->typeLogement2 = $logement->idTypeLogement;
			$resa->typeLogement3 = $logement->idTypeLogement;
			$resa->numeroChambre = $logement->numero;
			$resa->etat = $request->getPost('etat');

			$idReservation = $request->getPost('idReservation');
			if (!$idReservation) {
				$idReservation = $this->getResaTable()->majResa($resa);
				## maj de l etat du logement en occuper
				$this->getLogementTable()->updateLogement(array('idEtat' => '4'), array('id' => $idLogement));
			}


			$dansLaPile = $tablePile->getTable()->select(array('idReservation' => $idReservation))->current();

			if (!$dansLaPile) {
				//ajout dans pile
				$pile = new Pile();
				$data['idReservation'] = $idReservation;
				$data['idLocataire'] = $resa->idLocataire;
				$data['flag'] = "reservation";
				$pile->exchangeArray($data);
				$this->getPileTable()->empile($pile);
			}

			$view = new JsonModel(array(
						'success' => true,
						'idLocataire' => $idLocataire,
						'idReservation' => $idReservation,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	## retourn un array des champs de base table locataires facultatif
	## Edit : ajout du param idOngletFormulaire, pour ne prendre en compte que les champs des formulaires de l'onglet validé
	private function getChampsDeBaseLocFacultatif($loc, $idCamp, $idOngletFormulaire = 0)
	{
		if (!is_array($loc)) {
			$loc = get_object_vars($loc);
		}
		$champsFacultatifs = array();
		if ($idCamp) {
			foreach ($loc as $key => $val) {
				$tableCL = $this->getTableObjet('champs_formulaires');
				$select = $tableCL->getSql()->select();
				$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
				$select->where(array('formulaires.idCampagne' => $idCamp, 'champs_formulaires.equivalentSql' => trim($key), 'champs_formulaires.active' => 1, 'formulaires.active' => 1 ));
				if ($idOngletFormulaire > 0) {
					$select->where(array('formulaires.idOnglet' => $idOngletFormulaire));
				} elseif ($idOngletFormulaire != -1) {
					$select->where("(formulaires.idOnglet IS NULL OR formulaires.idOnglet = '')");
				}
				$row = $tableCL->selectWith($select)->current();
				if ($row && $row->obligatoire != 1) {
					$champsFacultatifs[trim($key)] = $val;
				}
			}
		}
		return $champsFacultatifs;
	}

	public function majlocataireAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$form = new LocataireForm();
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$conf = $this->getConfigurationTable()->getConfig(1);
		$tools = new Tools();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($request->isXmlHttpRequest()) {
			$post = $request->getPost();

			// echo "<pre>";
			// var_dump($post);
			// echo "</pre>";
			// die();

			$idReservation = $request->getPost('idResa');
			$idDp = $request->getPost('idDp');
			$idResaADupliquer = $request->getPost('idResaADupliquer', 0);
			$memeUsager = $request->getPost('memeUsager', 0);//pour dupliquer le dossier pour le meme usager ou non
			$idOngletFormulaire = $request->getPost('idOngletFormulaire', 0);

			$idLocataire = $request->getPost('id');
			$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
			$locOld = $this->getLocatairesTable()->getLocataire($idLocataire);
			$locOldAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($idLocataire, $adapter, $idReservation, $idDp);

			$now = date('Y-m-d');

			if ($loc) {
				$isAjoutLoc = false;
				$form->bind($loc);
			} else {
				$loc = new Locataires();
				$isAjoutLoc = true;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire idDp=$idDp");
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire POST=".json_encode($request->getPost()));
			$form->setInputFilter($loc->getInputFilter());

			$form->setData($request->getPost());

			$loc->exchangeArray($request->getPost());

			$sessionForm = new Container('formulaire');

			$majValsDynLogs = array();


			if ($idLocataire && !$memeUsager) {
				$post = $request->getPost();
				$isVide = true;
				foreach ($post as $key => $value) {
					if (!is_array($value) && trim($value) != "") {
						$isVide = false;
					}
				}
				if ($isVide) {
					$view = new JsonModel(array(
						'success' => false,
						'idLocataire' => $idLocataire,
						'isAjoutLoc' => false,
						'msgError' => 'Aucune valeur reçu',
						));

					$view->setTerminal(true);
					return $view;
				}
				//print_r($loc);exit();
				## modif pour maj les champs de base vide
				$locOptions = array();
				if (isset($post['idCampagne']) && $post['idCampagne'] > 0) {
					$champsFacultatifs = $this->getChampsDeBaseLocFacultatif($loc, $post['idCampagne'], $idOngletFormulaire);
					$locOptions['champsFacultatif'] = $champsFacultatifs;
				}
				##syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire loc=".json_encode($loc));
				##syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire locOptions=".json_encode($locOptions));

				// si on a le champ sexe alors on maj civilite à partir de sexe
				// sinon si on a le champ civilite alors on maj sexe à partir de civilité
				if (isset($post['sexe']) && !empty($post['sexe'])) {
					$loc->civilite = $post['sexe'];
				} elseif (isset($post['civilite']) && !empty($post['civilite'])) {
					$loc->sexe = $post['civilite'];
				}

				$this->getLocatairesTable()->majLocataire($loc, $locOptions);

				// var_dump($post);
				// die();

				if (isset($idDp) && $idDp > 0) {
					$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
					if ($dp) {
						$dpData = array();
						if (isset($post['dateEntree']) && $post['dateEntree'] != "" && $tools->isValideDate($post['dateEntree'])) {
							$dateEntree = date('Y-m-d', strtotime($post['dateEntree']));
							$dpData['dateEntree'] = $dateEntree;
						}
						if (isset($post['dateSortie']) && $post['dateSortie'] != "" && $tools->isValideDate($post['dateSortie'])) {
							$dateSortie = date('Y-m-d', strtotime($post['dateSortie']));
							$dpData['dateSortie'] = $dateSortie;
						}
						if (isset($post['etat']) && $post['etat'] != "") {
							$dpData['etat'] = $post['etat'];
						}
						if (!empty($dpData)) {
							$this->getTableObjet('domiciliations')->update($dpData, array('id' => $idDp)); // updateDp
						}

						foreach ($post as $keyRowPost => $rowPost) {
							//ajout champ catalogue
							if (strpos($keyRowPost, 'catalogues_') !== false) {
								if ($rowPost) {
									$this->getCatalogueTable()->insertCatalogueDp($rowPost, $idDp);
								}
								continue;
							}
						}

						/*
						===> déplacer tout en bas ou on maj déjà les champs dynamiques
						// Mise à jour des champs dynamiques
						// Récup le premier formulaire de dp
						$formDp = $this->getTableObjet('formulaires')->select(array('idCampagne'=>$post['idCampagne']))->toArray();

						// var_dump($post);die();

						foreach ($formDp as $key => $fdp) {
							$idFormDp = $fdp['id'];

							// Récup tous les champs dyn dont idTable correspond à la Dp
							$champsFromDp = $this->getTableObjet('champs_formulaires')->select(array('idFormulaire'=>$idFormDp, 'nature'=>'libre'))->toArray();

							// pour chaque champ de la requete, le retrouver dans les champs dyn et lui affecter sa valeur


							foreach ($post as $keyRowPost => $rowPost) {
								//ajout champ catalogue
								if(strpos($keyRowPost, 'catalogues_') !== false){
									if($rowPost) $this->getCatalogueTable()->insertCatalogueDp($rowPost,$idDp);
									continue;
								}
								foreach ($champsFromDp as $keyChampDp => $champDp) {
									$majValsDyn = array();
									if ($keyRowPost == $champDp['equivalentSql']) {
										// Si le champ à deja une valeur dyn, juste update la valeur, sinon créer une nouvelle ligne
										$valChampForm = $this->getTableObjet('valeurs_dynamiques')->select(array('idLocataire'=>$idLocataire, 'idChamp'=>$champDp['id']))->current();
										// var_dump($valChampForm);die();

										$champRoww = $this->getTableObjet('champs_formulaires')
											->select(array('id' => $champDp['id']))->current();

										// var_dump($champRoww);
										// var_dump($valChampForm);
										// var_dump($rowPost);

										if ($valChampForm) {
											$majValsDyn['idDp'] = $idDp;
											$majValsDyn['valeur'] = $rowPost;

											if ($champRoww->idType == 18) {
												if ($rowPost[0][0] != "") {
													$majValsDyn['valeur'] = $rowPost[0][0];
												}
											}

											// print_r($majValsDyn);
											$majValsDynLogs[] = array_merge($majValsDyn,array('id'=>$valChampForm['id'],'idChamp'=>$champDp['id']));

											$this->getTableObjet('valeurs_dynamiques')->update($majValsDyn,array('id'=>$valChampForm['id']));
										} else {
											// print_r($majValsDyn);

											$majValsDyn['idChamp'] = $champDp['id'];
											$majValsDyn['idLocataire'] = $idLocataire;
											$majValsDyn['idDp'] = $idDp;
											$majValsDyn['valeur'] = $rowPost;

											if ($champRoww->idType == 18) {
												$majValsDyn['valeur'] = $rowPost[0][0];
											}

											// var_dump($majValsDyn);die();

											$this->getTableObjet('valeurs_dynamiques')->insert($majValsDyn);
											$majValsDynLogs[] = $majValsDyn;
										}
									}
								}
							}
						}*/
					}
				}

				if (isset($post['idResa']) && $post['idResa'] > 0) {
					$champsResa = array('pasDeFacture',
										'delogementInterdit',
										'methodePaiement',
										'paiementComment',
										'cafNum','apl','rembAuto');
					$resa = $this->getResaTable()->getResa($post['idResa']);
					if ($resa) {
						## Lecture du champ statutCao avant MAJ  pour détecter les modifications
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$oldStatutCaoObj	= $this->getValeurschampdynamiqueTable()->getValeurByEquivalentSql('libre_statut_cao', $resa->idLocataire, $resa->id);
						if ($oldStatutCaoObj) {
							$oldStatutCao	= $oldStatutCaoObj->valeur;
						}
						$dateArrivee = $dateDepart = null;

						$resaData = array();
						//if(isset($post['dateArrivee']) && isset($post['dateDepart'])){
						if (isset($post['dateArrivee']) && $post['dateArrivee'] != "" && $tools->isValideDate($post['dateArrivee'])) {
							$dateArrivee = date('Y-m-d', strtotime($post['dateArrivee']));
							$resaData['dateArrivee'] = $dateArrivee;
						}
						if (isset($post['dateDepart']) && $post['dateDepart'] != "" && $tools->isValideDate($post['dateDepart'])) {
							$dateDepart = date('Y-m-d', strtotime($post['dateDepart']));
							$resaData['dateDepart'] = $dateDepart;
							$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
							if($modeCamp && $modeCamp->majEtatResaEnParti == 1) {
								if(strtotime($dateDepart) <= strtotime(date('Y-m-d'))) {
									$resaData['etat'] = 6;
								}
							}
						} elseif (isset($post['dateDepart']) && $post['dateDepart'] == "") {
							$resaData['dateDepart'] = null;
						}

						## maj dates theorique
						if (isset($post['dateArriveeTheorique']) && $post['dateArriveeTheorique'] != "" && $tools->isValideDate($post['dateArriveeTheorique'])) {
							$resaData['dateArriveeTheorique'] = date('Y-m-d', strtotime($post['dateArriveeTheorique']));
						}
						if (isset($post['dateDepartTheorique']) && $post['dateDepartTheorique'] != "" && $tools->isValideDate($post['dateDepartTheorique'])) {
							$resaData['dateDepartTheorique'] = date('Y-m-d', strtotime($post['dateDepartTheorique']));
						}

						$dateArrA = $dateArrivee ? $dateArrivee : $resa->dateArrivee;
						$dateDepA = $dateDepart ? $dateDepart : $resa->dateDepart;

						if ($dateDepA && substr($dateDepA, 0, 2) != '00') {
							$dateDepA = date('Y-m-d', strtotime($dateDepA));
						}

						//verification date arrivet et date départ
						if ($dateDepA && $dateDepA != "0000-00-00" && $dateDepA != "1970-01-01" && $dateArrA && strtotime($dateDepA) < strtotime($dateArrA)) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire dateDepA=$dateDepA dateArrA=$dateArrA");
							$msg = "Attention date de départ inférieure à la date arrivée";
							$view = new JsonModel(array(
								'success' => false,
								'idReservation' => $resa->id,
								'idLocataire' => $resa->idLocataire,
								'isAjout' => $isAjout,
								'msgError' => $msg,
							));

							$view->setTerminal(true);
							return $view;
						}

						if (isset($post['idLogement']) && $post['idLogement'] > 0) {
							$loge = $this->getLogementTable()->getLogement($post['idLogement']);

							if ($loge) {
								$idOldLogement = $resa->idLogement;
								$resaData['numeroChambre'] = $loge->numero;
								$resaData['idTypeLogementAttribue'] = $loge->idTypeLogement;
								$resaData['idLogement'] = $loge->id;

								$campMode = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);

								if ($resa->etat == 1 || $resa->etat == 10) {
									$resaData['idLogement'] = $loge->id;
									## Vérification du mode de validation pour décider si on passe en affecté ou en Confirmé
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($campMode &&
										(($campMode->modeValidationDemande == 3) ||
										($campMode->passageAffecteVersConfirmeManuel) ||
										($campMode->modeValidationDemande == 1 && $campMode->priseEmpreinteCBdemande && strpos($campMode->priseEmpreinteCBdemande, 'avecPriseEmpreinteCBpourFraisInitiaux') !== false))
									) {
										$resaData['etat'] = 2;
									} else {
										$resaData['etat'] = 3;
										if (!empty($resaData['dateArrivee']) && strtotime($resaData['dateArrivee']) <= strtotime($now)) {
											$resaData['etat'] = 7;
										}
									}
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire etat=".$resa->etat." campMode=".json_encode($campMode)." resaData=".json_encode($resaData));

									if (!$idOldLogement) {
										if (!empty($resaData['dateArrivee']) && substr($resaData['dateArrivee'], 0, 2) != "00" && strtotime($resaData['dateArrivee']) != strtotime($resa->dateArrivee)) {
											$resa->dateArrivee = $resaData['dateArrivee'];
											$this->getResaTable()->updateResa(array('dateArrivee' => $resaData['dateArrivee']), array('id' => $post['idResa']));
										}
										if (!$resa->dateArrivee || substr($resa->dateArrivee, 0, 2) == "00") {
											$view = new JsonModel(array(
													'success' => false,
													'idReservation' => $resa->id,
													'idLocataire' => $resa->idLocataire,
													'isAjout' => $isAjout,
													'msgError' => "Date arrivée absente pour affecter le logement",
												));

											$view->setTerminal(true);
											return $view;
										}

										$ret = $this->affecterLogement($resa->id, $loge->id);
										if (is_object($ret)) {
											$vars = $ret[0];
											if (array_key_exists('success', $vars) && !$vars['success'] && array_key_exists('msg', $vars) && $vars['msg'] != "") {
												$view = new JsonModel(array(
													'success' => false,
													'idReservation' => $resa->id,
													'idLocataire' => $resa->idLocataire,
													'isAjout' => $isAjout,
													'msgError' => $vars['msg'],
												));

												$view->setTerminal(true);
												return $view;
											} elseif ($campMode && !$campMode->passageAffecteVersConfirmeManuel && array_key_exists('success', $vars) && $vars['success']) {
												//deja maj lors d'affectation dans PlanningController.php
												unset($resaData['etat']);
											}
										} elseif (is_array($ret)) {
											if (array_key_exists('success', $ret) && !$ret['success'] && $ret['msg'] != '') {
												$view = new JsonModel(array(
													'success' => false,
													'idReservation' => $resa->id,
													'idLocataire' => $resa->idLocataire,
													'isAjout' => $isAjout,
													'msgError' => $ret['msg'],
												));

												$view->setTerminal(true);
												return $view;
											} elseif ($campMode && !$campMode->passageAffecteVersConfirmeManuel && array_key_exists('success', $ret) && $ret['success']) {
												//deja maj lors d'affectation dans PlanningController.php
												unset($resaData['etat']);
											}
										}
										//'msg'=>$msg,
										//'success'=>$success,
									}
								} elseif($campMode && $campMode->chgLogSansNouvelleResa == 1) {
									$resaData['idLogement'] = $loge->id;//on maj le logement direct
								}
								if($campMode->chgLogSansNouvelleResa == 1 && $resa->numDossier && $resa->codeSite && $loge->id != $idOldLogement) {

									//changement cote bredea si meme site
									$return = $this->changementLogementPms($resa->id, $loge->id, date('Y-m-d'));

									if(is_array($return) && !empty($return)) {
										$msgChange = "";
									} elseif($return) {
										//msg retourne de la fonction bredea
										$msgChange = $return;
									} else {
										//pas de changement erreur
										$msgChange = "Changement bloquer cote Bredea";
									}
									if($msgChange != "") {
										$view = new JsonModel(array(
												'success' => false,
												'idReservation' => $resa->id,
												'idLocataire' => $resa->idLocataire,
												'isAjout' => $isAjout,
												'msgError' => $msgChange,
										));

										$view->setTerminal(true);
										return $view;
									}
								}
							}
						}

						if (isset($post['idMenage']) && $post['idMenage'] > 0) {
							$resaData['idMenage'] = $post['idMenage'];
							if ($resa->idMenage != $post['idMenage']) {
								$this->saveMenageHistorique($post['idResa'], $resa->idMenage, $post['idMenage']);
							}
						}
						if (isset($post['idStatutFamilial']) && $post['idStatutFamilial'] > 0) {
							$resaData['idStatutFamilial'] = $post['idStatutFamilial'];
						}

						foreach($champsResa as $champName) {
							if(isset($post[$champName])) {
								$resaData[$champName] = $post[$champName];
							}
						}

						## maj mode paiement presta en virement si rib controller
						//verification si on a déjà les champs RIB rempli
						if (array_key_exists('statutRIB', $post)) {
							$msgCheck = $this->isRIBRempli($resa->id);
							if ($msgCheck == 'ok') {
								if (array_key_exists('statutRIB', $post) && $post['statutRIB'] == 'controler') {
									$this->getPrestaTable()->majModePaiement($resa->id, 'Virement');
								}
							} else {
								$erreurs[] = $msgCheck;
								$resaData['statutRIB'] = null;
							}
						}

						## maj statut et date fin validité attestation assurance
						if (isset($post['statutDoc_certificatAssur']) && $post['statutDoc_certificatAssur'] != '') {
							$resaData['statutAssur'] = $post['statutDoc_certificatAssur'];
						}
						if (isset($post['finValidite_certificatAssur']) && $post['finValidite_certificatAssur'] != '') {
							$resaData['dateFinAssur'] = date('Y-m-d', strtotime($post['finValidite_certificatAssur']));
						}

						// controle date depart
						if (!empty($resaData['dateDepart']) && $resaData['dateDepart']) {
							$dateDep = $resaData['dateDepart'];
							if ($dateDep != $resa->dateDepart) {
								$isOccupe = $this->getResaTable()->checkEndDate($dateDep, $resa->idLogement, $resa->id, array(2, 3, 7, 15));//false => dispo
								$isDispo = $this->checkDisponibiliteLogementBredea($resa->id, $dateDep);

								$enTravaux = false;
								$msgTravaux = "";
								$ptl = $this->getPeriodesTravaux($resa->idLogement);
								foreach ($ptl as $pt) {
									if (strtotime($dateDep) >= strtotime($pt->dateDebutTravaux) && strtotime($dateDep) <= strtotime($pt->dateFinTravaux)) {
										$msgTravaux = "Logement ".$resa->numeroChambre." en travaux entre ".date('d-m-Y', strtotime($pt->dateDebutTravaux))." et ".date('d-m-Y', strtotime($pt->dateFinTravaux));
										$enTravaux = true;

									}
								}

								$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $resa->dateArrivee, $dateDep);

								if (!$isDispo || $isOccupe || $enTravaux || $bloquerCSMsg != '') {
									if (!$isDispo) {
										$msg = "Logement non disponible pour la nouvelle date de départ $dateDep, veuillez vérifier le planning bredea";
									} elseif ($enTravaux) {
										$msg = $msgTravaux;
									} elseif ($bloquerCSMsg != '') {
										$msg = $bloquerCSMsg;
									} else {
										$msg = "Logement non disponible pour la nouvelle date de départ $dateDep";
									}
									$view = new JsonModel(array(
											'success' => false,
											'idReservation' => $resa->id,
											'idLocataire' => $resa->idLocataire,
											'isAjout' => $isAjout,
											'msgError' => $msg,
									));

									$view->setTerminal(true);
									return $view;
								}

								// Supprimer les renonces si existe
								$renonces = $this->getRdvRenonceTable()->getByIdReservations($resa->id)->toArray();
								if (count($renonces) > 0) {
									foreach ($renonces as $key => $renonce) {
										$this->getRdvRenonceTable()->delete((int)$renonce['id']);
									}
								}

								// Supprimer Rdv si existe
								$rdv = $this->getRdvTable()->getByIdResa($resa->id)->toArray();
								if (count($rdv) > 0) {
									$this->getRdvTable()->delete(array('idReservations' => (int)$resa->id));
								}
							}
						}

						// controle date depart
						if (!empty($resaData['dateArrivee']) && $resaData['dateArrivee']) {
							$dateDep = !empty($resaData['dateDepart']) ? $resaData['dateDepart'] : $resa->dateDepart;
							$dateArr = $resaData['dateArrivee'];
							if ($dateArr != $resa->dateArrivee) {
								$isOccupe = $this->getResaTable()->checkStartDate($dateArr, $resa->idLogement, $resa->id, array(2, 3, 7, 15));//false => dispo

								$isDispo = $this->checkDisponibiliteLogementBredea($resa->id, $dateArr);

								$enTravaux = false;
								$msgTravaux = "";
								$ptl = $this->getPeriodesTravaux($resa->idLogement);
								foreach ($ptl as $pt) {
									if (strtotime($dateArr) >= strtotime($pt->dateDebutTravaux) && strtotime($dateArr) <= strtotime($pt->dateFinTravaux)) {
										$msgTravaux = "Logement ".$resa->numeroChambre." en travaux entre ".date('d-m-Y', strtotime($pt->dateDebutTravaux))." et ".date('d-m-Y', strtotime($pt->dateFinTravaux));
										$enTravaux = true;

									}
								}

								$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $dateArr, $dateDep);

								if (!$isDispo || $isOccupe || $enTravaux || $bloquerCSMsg != '') {
									if (!$isDispo) {
										$msg = "Logement non disponible pour la nouvelle date de arrivée $dateArr, veuillez vérifier le planning bredea";
									} elseif ($enTravaux) {
										$msg = $msgTravaux;
									} elseif ($bloquerCSMsg != '') {
										$msg = $bloquerCSMsg;
									} else {
										$msg = "Logement non disponible pour la nouvelle date de arrivée $dateArr";
									}
									$view = new JsonModel(array(
											'success' => false,
											'idReservation' => $resa->id,
											'idLocataire' => $resa->idLocataire,
											'isAjout' => $isAjout,
											'msgError' => $msg,
									));

									$view->setTerminal(true);
									return $view;
								}
							}
						}
						if ($post['colocataire']) {
							$resaData['colocataire'] = $post['colocataire'];
						}
						if ($post['idUser']) {
							$resaData['idUser'] = $post['idUser'];
						}

						if (isset($post['residenceOrientation']) && $post['residenceOrientation'] != "") {
							$resaData['residenceOrientation'] = $post['residenceOrientation'];
						}

						if (isset($post['doc_attestationBourse']) && $post['doc_attestationBourse'] != "") {
							$resaData['attestationBourse'] = $post['doc_attestationBourse'];
						}

						if (isset($post['sousEtat_envoiPmsAutorise'])) {
							$sousEtat	= $resa->sousEtat ? explode(',', $resa->sousEtat) : array();

							$key		= array_search("envoiPmsAutorise", $sousEtat);
							if ($post['sousEtat_envoiPmsAutorise']) {
								if ($key === false) {
									$sousEtat[]	= 'envoiPmsAutorise';
								}
							} else {
								if ($key !== false) {
									unset($sousEtat[$key]);
								}
							}
							$newSousEtat	= implode(',', $sousEtat);
							if ($newSousEtat != $resa->sousEtat) {
								$resaData['sousEtat']	= $newSousEtat;
							}
						}
						if (!empty($resaData)) {
							$resaOld = $resa;
							if ($resaOld->numResa) {
								if (!empty($resaData['dateArrivee'])) {
									if ($resaOld->etat == 7) {
										if (strtotime($resaData['dateArrivee']) < strtotime($resaOld->dateArrivee)) {
											$resaData['dateArriveeTheorique'] = $resaData['dateArrivee'];//
										}
									}
								}
								/*Sur la date de départ si elle est dans et futur par rapport à la date initial il faut changer aussi la date de fin de contrat
								sinon on ne change que la date de départ*/
								/*if(strtotime($resa->dateDepart) <= strtotime($resaOld->dateDepart)){
									$resa->dateDepartTheorique = $resaOld->dateDepartTheorique;
								}
								/*
								correction du 04-11-2017 :
								si la date de depart est supérieur à la date de fin de facturation alors on MAJ la date de fin de facturation
								*/
								if (!empty($resaData['dateDepart']) && $resaData['dateDepart']) {
									if (strtotime($resaData['dateDepart']) != strtotime($resaOld->dateDepart)) {
										if (strtotime($resaData['dateDepart']) <= strtotime($resaOld->dateDepartTheorique)) {
											//pas changer
										} else {
											// on change la date fin de facturation
											$resaData['dateDepartTheorique'] = $resaData['dateDepart'];

											// changement de flags notification caf
											$resaData['cafChangementDateDepartTheorique'] = '1';
										}
									}
								}
							}

							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire avantUpdateResa");
							$this->getResaTable()->updateResa($resaData, array('id' => $post['idResa']));
						}

						// maj des choix de logement
						if (isset($post['maxChoix']) && $post['maxChoix'] > 0) {
							for ($i = 1; $i <= $post['maxChoix']; $i++) {
								if (isset($post['modeChoix']) && $post['modeChoix'] == 'typeLogementBase') {
									//on chercher la valeyr dans choixTypeLo1 = par exemple residence-34-115 (115 le idTypeLogement)
									if (isset($post['choixTypeLo'.$i])) {
										$idsChoixTypeLo = explode('-', $post['choixTypeLo'.$i]);
										$idTypeLogement = $idsChoixTypeLo[count($idsChoixTypeLo) - 1 ];
									}
									if(isset($post['residenceOptions'.$i]) && !isset($post['residence'.$i])){
										$post['residence'.$i] = $post['residenceOptions'.$i];
									}
								} else {
									$idTypeLogement = $post['idTypeLogement'.$i];
								}
								if (isset($idTypeLogement) && $idTypeLogement > 0) {
									$choixs = $this->getChoixTable()->getChoixByResaNumero($post['idResa'], $i, false);
									$dataChoix = array();
									$dataChoix['idTypeLogement'] = $idTypeLogement;
									$dataChoix['idResidence'] = isset($post['residence'.$i]) ? $post['residence'.$i] : 0;
									$dataChoix['idBatiment'] = isset($post['batiment'.$i]) ? $post['batiment'.$i] : 0;

									$loyer = $montantCaution = $fraisGestion = $adhesion = $cotisation = 0;
									if (isset($sessionForm->tarifs[$idTypeLogement])) {
										$tarif = $sessionForm->tarifs[$idTypeLogement];
										if ($tarif) {
											$loyer = $tarif->loyer;
											$montantCaution = $tarif->montantCaution;
											$fraisGestion = $tarif->fraisGestion;
											$adhesion = $tarif->adhesion;
											$cotisation = $tarif->cotisation;
										}
									}

									$dataChoix['loyer'] = $loyer;
									$dataChoix['montantCaution'] = $montantCaution;
									$dataChoix['fraisGestion'] = $fraisGestion;
									$dataChoix['adhesion'] = $adhesion;
									$dataChoix['cotisation'] = $cotisation;

									if ($choixs) {
										if ($choixs->idTypeLogement != $idTypeLogement) {
											//on ne maj pas les frais
											unset($dataChoix['loyer']);
											unset($dataChoix['montantCaution']);
											unset($dataChoix['fraisGestion']);
											unset($dataChoix['adhesion']);
											unset($dataChoix['cotisation']);
											syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire updateDataChoix=".json_encode($dataChoix));
											$this->getTable('choix_typelogement')->update($dataChoix, array('id' => $choixs->id));
										}
									} else {
										$dataChoix['idReservation'] = $post['idResa'];
										$dataChoix['numeroChoix'] = $i;
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idReservation=$idReservation idLocataire=$idLocataire insertDataChoix=".json_encode($dataChoix));
										$this->getTable('choix_typelogement')->insert($dataChoix);
									}
								}
							}//end for
						}

						//maj champs ressources
						$ressData = array();
						if (isset($post['ressEntree']) && $post['ressEntree'] != "") {
							$ressData['ressEntree'] = $post['ressEntree'];
						}
						if (isset($post['nbrPersEntree']) && $post['nbrPersEntree'] != "") {
							$ressData['nbrPersEntree'] = $post['nbrPersEntree'];
						}
						if (isset($post['nbrPersChargeEntree']) && $post['nbrPersChargeEntree'] != "") {
							$ressData['nbrPersChargeEntree'] = $post['nbrPersChargeEntree'];
						}
						if (isset($post['handicapEntree'])) {
							$ressData['handicapEntree'] = $post['handicapEntree'];
						}
						if (isset($post['finValiditeHandicapEntree']) && $post['finValiditeHandicapEntree'] != "") {
							$ressData['finValiditeHandicapEntree'] = $post['finValiditeHandicapEntree'];
						}

						//on prend le champs date fin validité document
						if (!$ressData['finValiditeHandicapEntree'] && isset($post['finValidite_preuveHandicapEntree']) && $post['finValidite_preuveHandicapEntree'] != "") {
							$ressData['finValiditeHandicapEntree'] = $post['finValidite_preuveHandicapEntree'];
						}

						if (isset($post['doc_preuveHandicapEntree']) && $post['doc_preuveHandicapEntree'] != "") {
							$ressData['preuveHandicapEntree'] = $post['doc_preuveHandicapEntree'];
						}
						if (isset($post['statutDoc_preuveHandicapEntree'])) {
							$ressData['statutPreuveHandicapEntree'] = $post['statutDoc_preuveHandicapEntree'];
						}

						if (!empty($ressData) && !empty($post['idResa'])) {
							$ressData['idResa'] = $post['idResa'];
							$this->getPLAITable()->saveRessource($ressData);
						}

						## maj champs SEPA
						$sepaData = array();

						if (isset($post['prelevementSEPA']) && $post['prelevementSEPA'] != "") {
							$sepaData['prelevementSEPA'] = $post['prelevementSEPA'];
						}
						if (isset($post['jourPrelevementSEPA']) && $post['jourPrelevementSEPA'] != "") {
							$sepaData['jourPrelevementSEPA'] = $post['jourPrelevementSEPA'];
						}
						if (isset($post['typePrelevementSEPA']) && $post['typePrelevementSEPA'] != "") {
							$sepaData['typePrelevementSEPA'] = $post['typePrelevementSEPA'];
						}
						if (isset($post['montantPrelevementSEPA']) && $post['montantPrelevementSEPA'] != "") {
							$sepaData['montantPrelevementSEPA'] = $post['montantPrelevementSEPA'];
						}
						if (isset($post['doc_mandatSEPA']) && $post['doc_mandatSEPA'] != "") {
							$sepaData['mandatSEPA'] = $post['doc_mandatSEPA'];
						}
						if (isset($post['statutDoc_mandatSEPA']) && $post['statutDoc_mandatSEPA'] != "") {
							$sepaData['statutDoc_mandatSEPA'] = $post['statutDoc_mandatSEPA'];
						}
						if (isset($post['finValidite_mandatSEPA']) && $post['finValidite_mandatSEPA'] != "") {
							$sepaData['finValidite_mandatSEPA'] = $post['finValidite_mandatSEPA'];
						}
						if (isset($post['ibanSEPA']) && $post['ibanSEPA'] != "") {
							$sepaData['ibanSEPA'] = $post['ibanSEPA'];
						}
						if (isset($post['bicSEPA']) && $post['bicSEPA'] != "") {
							$sepaData['bicSEPA'] = $post['bicSEPA'];
						}
						if (isset($post['domiciliationSEPA']) && $post['domiciliationSEPA'] != "") {
							$sepaData['domiciliationSEPA'] = $post['domiciliationSEPA'];
						}
						if (isset($post['dateMandatSEPA']) && $post['dateMandatSEPA'] != "") {
							$sepaData['dateMandatSEPA'] = $post['dateMandatSEPA'];
						}

						if (!empty($sepaData) && !empty($post['idResa'])) {
							$sepaData['idReservation'] = $post['idResa'];
							$this->getSEPATable()->save($sepaData);
						}

						## maj champs catalogues
						foreach ($post as $champName => $value) {
							if (strpos($champName, 'catalogues_') !== false) {
								if ($value) {
									$this->getCatalogueTable()->insertCatalogueResa($value, $resa->id);
								}
								continue;
							}
						}
					}
				}
			} else {
				//correction ajout des locataires null
				$post = $request->getPost();
				$isVide = true;
				foreach ($post as $key => $value) {
					if (!is_array($value) && trim($value) != "") {
						$isVide = false;
					}
				}

				if ($isVide) {
					$view = new JsonModel(array(
						'success' => false,
						'idLocataire' => 0,
						'isAjoutLoc' => false,
						'msg' => '',
						//'msg'=>"Informations bien enregistrées",

						));

					$view->setTerminal(true);
					return $view;
				}
				$idLocataire = $this->getLocatairesTable()->saveLocataire($loc);
				$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				$form->bind($loc);

				##creation de la resa
				if ($idResaADupliquer > 0) {
					$tableResa = $this->getTableObjet('reservations');
					$res = $tableResa->select(array('id' => $idResaADupliquer))->current();
					if ($res) {
						$dataResa = get_object_vars($res);
						$dataResa['idLocataire'] = $idLocataire;
						unset($dataResa['id']);
						unset($dataResa['idLogement']);
						unset($dataResa['numeroChambre']);
						unset($dataResa['idTypeLogementAttribue']);
						unset($dataResa['idAncienneResa']);
						unset($dataResa['idNouvelleResa']);
						unset($dataResa['idPMS']);
						unset($dataResa['numResa']);
						unset($dataResa['numDossier']);
						unset($dataResa['codeSite']);
						unset($dataResa['dateOption']);
						unset($dataResa['flag']);
						$dataResa['dateDemandeReservation'] = date('Y-m-d H:i:s');
						foreach ($dataResa as $k => $v) {
							if (!empty($post[$k]) && $post[$k] != '') {
								$val = $post[$k];
								if ($k == 'dateArrivee' || $k == 'dateDepart') {
									$val = date('Y-m-d', strtotime($val));
								}
								$dataResa[$k] = $val;
							}
						}
						if(empty($post['dateArriveeTheorique']) || $post['dateArriveeTheorique'] == '') {
							$dataResa['dateArriveeTheorique'] = $dataResa['dateArrivee'];
						}
						if(empty($post['dateDepartTheorique']) || $post['dateDepartTheorique'] == '') {
							$dataResa['dateDepartTheorique'] = $dataResa['dateDepart'];
						}
						if(empty($post['dateDepart']) || $post['dateDepart'] == '') {
							unset($dataResa['dateDepart']);
						}
						if (empty($post['idStatutFamilial'])) {
							unset($dataResa['idStatutFamilial']);
						}
						$tableResa->insert($dataResa);
						$idResa = $tableResa->lastInsertValue;
						$post['idResa'] = $idResa;
						$isAjoutLoc = false;
					}
				}
			}

			## MAJ CHAMPS DYNAMIQUE
			$session = new Container('extra');
			$champsDynamiques = $session->allFields;

			$formsAllFields = $sessionForm->formsAllFields;
			$formulaires = $sessionForm->formulaires;

			$modeCampagne = $this->getCampagneTable()->getCampagneMode($post['idCampagne']);

			$recalculerPresta = false;
			$valeursObjArr = array();

			$tableChampsObligatoires = $this->getTableObjet('champs_obligatoires');
			$champsFormTable = $this->getTableObjet('champs_formulaires');
			$post = $request->getPost();
			$post['idLocataire'] = $idLocataire;
			foreach ($formulaires as $frm) {
				$all = $formsAllFields[$frm->id];
				foreach ($all as $champ) {
					if ($champ->nature == "libre") {
						//foreach ($champsDynamiques as $champ) {
						$champName = $champ->equivalentSql;
						$typeChamp = $this->getTypeChamp($champ->idType);
						if ($typeChamp == "File") {
							$champName = "doc_".$champName;
						}
						$valeur = $request->getPost($champName);


						if ($champ->idParent) {
							//on recup le champ parent
							$champParent = $champsFormTable->select(array('id' => $champ->idParent))->current();
							if (!$champParent) {
								continue;
							}

							// on set la valeur à partir du champ parent
							if (isset($_POST[$champParent->equivalentSql])) {
								$valeur = $request->getPost($champParent->equivalentSql);
							}

							$champ = $champParent;
						}
						## Edit le 14/11/2022 par FTH : controle pour le pb de valeurs dynamiques vidé, vu sur gammes
						if($modeCampagne && $modeCampagne->champsObligatoiresFormOuvert == 1) {
							//ne rien faire
						} else {
							if($champ->obligatoire == 1 && isset($post[$champName]) && ($valeur == null || (is_array($valeur) && empty($valeur)) || (!is_array($valeur) && trim($valeur) == ''))) {
								$view = new JsonModel(array(
									'success' => false,
									'idLocataire' => $idLocataire,
									'isAjoutLoc' => false,
									'msgError' => 'Aucune valeur reçu pour le champ obligatoire '.$champ->libelle,
									'idResaADupliquer' => $idResaADupliquer,
									'idResaDupliquer' => $idResa, //idResa créer à la duplication pour ne pas en faire des doublon à chaque validation du form
									));

								$view->setTerminal(true);
								return $view;
								continue;
							}
						}
						if (1) {
							$valeursObj = new Valeurschampdynamique();
							$valeursObj->idChamp = $champ->id;
							$valeursObj->valeur = $valeur;
							$valeursObj->idLocataire = $idLocataire;
							$valeursObj->typeChamp = $typeChamp;
							if (isset($post['idResa']) && $post['idResa'] > 0) {
								$valeursObj->idReservation = $post['idResa'];
							}

							if (isset($post['idDp']) && $post['idDp'] > 0) {
								$valeursObj->idDp = $post['idDp'];
							}

							if ($typeChamp == "File") {
								$statutDoc	= $request->getPost("statutDoc_".$champ->equivalentSql);
								if ($statutDoc) {
									$valeursObj->statutDoc = $statutDoc;
								}
								if ($champ->renouvelable) {
									$finValidite	= $request->getPost("finValidite_".$champ->equivalentSql);
									if ($finValidite && $finValidite != '0000-00-00') {
										$valeursObj->finValidite = date('Y-m-d', strtotime($finValidite));
									}
								}
							}


							##verification changement rib
							if ($valeur && $valeursObj->idReservation && ($champ->idType == 15 || $champ->idType == 16 || $champ->nomXML == 'rib_nomrib')) {
								$this->checkMajStatutRIB($valeursObj->idReservation, $champ->id, $valeur);
							}

							##verification changement champ lié à une formule
							if ($valeursObj->idReservation) {
								$rep = $this->getPrestaTable()->isPrestaDynField($valeursObj->idReservation, $champ->equivalentSql);
								if ($rep != "ok") {
									$this->messages['majLocataire']['error'][] = $rep;
									continue;
								}
							}

							if (($champ->idType == 5 || $champ->idType == 12)) {

								// on verifie si on modifie un de ces champs idType 5 ou 12
								if ($valeur && !empty($locOldAllInfosObj[$champ->equivalentSql]) &&  $locOldAllInfosObj[$champ->equivalentSql] != $valeur) {
									$recalculerPresta = true;// on recalcule la presta que si on modifie un champ nombre ou monétaire
								} elseif ($valeur && empty($locOldAllInfosObj[$champ->equivalentSql])) {
									$recalculerPresta = true;
								}
							}

							if ($champ->idType == 18) {
								if ($valeur[0][0] != "") {
									$valeursObj->valeur = $valeur[0][0];
								}
							}


							$ret = $this->getValeurschampdynamiqueTable()->save($valeursObj);
							if ($ret > 0) {
								$valeursObj->id = $ret;
								$valeursObjArr[] = array('insert' => $valeursObj);
							} else {
								$valeursObjArr[] = array('update' => $valeursObj);
							}
							## on enlève le champ si c'est dans les champs obligatoire
							if($valeursObj->valeur && $valeursObj->idReservation){
								$tableChampsObligatoires->delete(array('idResa'=>$valeursObj->idReservation,'idChamp'=>$valeursObj->idChamp));
							}
						}
						//}
					} else {
						if (($champName = $champ->equivalentSql) && $champ->idType) {
							$typeChamp = $this->getTypeChamp($champ->idType);
							if ($typeChamp == "File") {
								$champName = "doc_".$champName;
								$valeur = $request->getPost($champName);
								##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idReservation idChamp=".$champ->id." champName=$champName typeChamp=$typeChamp valeur=$valeur");
							}
						}
					}
				}
			}

			## //traitment champs avec champ commun
			foreach ($formulaires as $frm) {
				$all = $formsAllFields[$frm->id];
				foreach ($all as $champ) {
					if($champ->idChampCommun > 0) {
						$this->copierValeurChampCommun($champ, $post);
					}
				}
			}

			if (!empty($valeursObjArr)) {
				## Notification éventuelle des mails de statut CAO
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$idResa1		= $resa->id;
					$idCampagne		= $resa->idCampagne;
					$modeEnvoiDemandePMS	= $this->getCampagneTable()->getCampagne($idCampagne)->modeEnvoiDemandePMS;

					## Lecture du champ dynamique de statut CAO
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$champsStatutCao	= $this->getChampdynamiqueTable()->getChampsActif(array('champs_dynamiques.nom' => 'libre_statut_cao', 'idCampagne' => $idCampagne));
					if (count($champsStatutCao) > 0) {
						$champStatutCao		= reset($champsStatutCao);
						$valeurStatutCao	= $request->getPost($champStatutCao->equivalentSql);
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa1 idCampagne=$idCampagne valeurStatutCao=$valeurStatutCao");

						$libelleStatutCao	= "";
						$optionsStatutCao	= $this->getSelectOptions($champStatutCao->sourceListe);
						if ($optionsStatutCao) {
							foreach ($optionsStatutCao as $optionStatutCao) {
								if ($optionStatutCao->id == $valeurStatutCao) {
									$libelleStatutCao	= $optionStatutCao->valeur;
									break;
								}
							}
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa1 idCampagne=$idCampagne modeEnvoiDemandePMS=$modeEnvoiDemandePMS oldStatutCao=$oldStatutCao valeurStatutCao=$valeurStatutCao ($libelleStatutCao)");
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa1 idCampagne=$idCampagne getChampStatutCao ERROR-exception=".$ex->getMessage());
				}
				## Envoi éventuel des mails de notification si changement de statut CAO
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($oldStatutCao != $valeurStatutCao) {
					try {
						if ($libelleStatutCao == 'REFUS') {
							$this->envoyerMail($idResa1, 0, 0, array('code' => 'commission_refus'));
						} elseif ($libelleStatutCao == 'ACCORD' && $modeEnvoiDemandePMS == 'ApresCommissionEtAutorisation') {
							$this->envoyerMail($idResa1, 0, 0, array('code' => 'commission_accord'));
						}
						## si changement de statut vers en attente et que la demande est en etat 1, on la remet en etat 11(attente)
						if (strtoupper($libelleStatutCao) == 'EN ATTENTE' && $resa->id && $resa->etat == 1) {
							$this->getResaTable()->updateResa(array('etat' => 11), array('id' => $resa->id));
							## envois de mail Demande en attente
							$this->envoyerMail($idResa1, 25);
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa1 idCampagne=$idCampagne sendMail ERROR-exception=".$ex->getMessage());
					}
				}
			}

			if (!empty($valeursObjArr)) {
				$log = new Logs();
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				//$log->idLocataire = $idLocataire;
				//if($valeursObj->idReservation) $log->idReservation = $valeursObj->idReservation;
				$log->operation = "BO : Update fiche usager(valeurs dynamiques) dossier : ".$locOld->nom.' '.$locOld->prenom;
				$log->dataBefore = $post;
				$log->dataAfter = $valeursObjArr;
				$log->tableName = "valeurs_dynamiques";
				$this->getLogsTable()->saveLogs($log);
			}

			##MAJ BREDEA
			if (isset($idDp) && $idDp > 0) {
				$resaDeLocDp = $this->getResaTable()->getLocLastResa($idLocataire);
				if ($resaDeLocDp) {
					$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($idLocataire, $adapter, 0, $idDp);
					$diff = $log->arrayDiff($locOldAllInfosObj, $locAllInfosObj);
					if (!empty($diff)) {
						$this->updateResaPmsAndSig($resaDeLocDp->id);
					}
				}
			}
			if ($idReservation) {
				$resa = $this->getResaTable()->getResa($idReservation);
				if ($resa && $resa->idLocataire == $loc->id) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idReservation");
					$this->updateResaPmsAndSig($idReservation);
				}

				## recalculation des prestation calculé
				if ($recalculerPresta) {
					$this->getPrestaTable()->calculerPrestationsDeResa($idReservation);
				}
			}

			if (isset($idDp) && $idDp > 0) {
				$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($idLocataire, $adapter, 0, $idDp);
				$log = new Logs();
				if ($conf->debug == 1) {
					$diff = $log->arrayDiff($locOldAllInfosObj, $locAllInfosObj);
				} else {
					$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
					$diff = $log->arrayDiff($locOld, $loc);
				}

				$log = new Logs();

				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->idLocataire = $idLocataire;
				$log->operation = "BO : Update fiche usager dossier Dp : ".$loc->nom.' '.$loc->prenom;
				$log->dataBefore = $diff['before'];

				$log->dataAfter = $diff['after'];

				$log->tableName = "Domiciliations";

				$this->getLogsTable()->saveLogs($log);
			} else {
				$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($idLocataire, $adapter, $idReservation, $idDp);
				$log = new Logs();
				if ($conf->debug == 1) {
					$diff = $log->arrayDiff($locOldAllInfosObj, $locAllInfosObj);
				} else {
					$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
					$diff = $log->arrayDiff($locOld, $loc);
				}

				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->idLocataire = $idLocataire;
				$log->idReservation = $idReservation;
				$log->operation = "BO : Update fiche usager : ".$loc->nom.' '.$loc->prenom;
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
				$log->tableName = "Locataires";

				if(!empty($diff['before']) || !empty($diff['after'])) {
					$this->getLogsTable()->saveLogs($log);
				}
			}


			/*$tablePile = new Tables('pile',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$dansLaPile = $tablePile->getTable()->select(array('idLocataire'=>$idLocataire))->current();

			if(!$dansLaPile){
				//ajout dans pile
				$pile = new Pile();
				$data['idReservation'] = null;
				$data['idLocataire'] = $idLocataire;
				$data['flag'] = "reservation";
				$pile->exchangeArray($data);
				$this->getPileTable()->empile($pile);
			}*/

			$view = new JsonModel(array(
						'success' => true,
						'idLocataire' => $idLocataire,
						'isAjoutLoc' => $isAjoutLoc,
						'msgError' => (!empty($this->messages['majLocataire']['error'])) ? implode('<br />', $this->messages['majLocataire']['error']) : '',
						'idReservation' => $idReservation,
						'idResaADupliquer' => $idResaADupliquer,
			//'msg'=>"Informations bien enregistrées",

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function affecterLogeFromUrlAction()
	{
		$idResa = (isset($_GET['idResa']) && $_GET['idResa'] != "") ? (int)$_GET['idResa'] : null;
		$idLoge = (isset($_GET['idLoge']) && $_GET['idLoge'] != "") ? (int)$_GET['idLoge'] : null;
		if ($idResa && $idLoge) {
			$ret = $this->affecterLogement($idResa, $idLoge);
			if (is_object($ret)) {
				$vars = $ret[0];
				echo $vars['msg'];
			}
		} else {
			echo "Manque la variable idResa=xxx&idLoge=xxx";
		}

		exit();
	}


	## action forwarder vers planningController.php
	public function affecterLogement($idResa, $idLogement)
	{
		try {
			$return = $this->forward()->dispatch('Reservation\Controller\Planning', array('action' => 'affecterLogementDepuisFicheUsager', 'mesParams' => array('idResa' => $idResa, 'idLogementAffecter' => $idLogement, 'isPlanning' => false)));


			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLogement=$idLogement apres affecterLogementDepuisFicheUsager");
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Appel du controlleur de planning : ERROR-exception=".$ex->getMessage());
			$return = $ex->getMessage();
		}
		return $return;
	}

	## pour l'instant que bredea meme site
	private function changementLogementPms($idResa, $idNewLogement, $dateChangement)
	{
		$return = array();
		if ($idResa && $idNewLogement && $dateChangement) {
			$resa	= $this->getResaTable()->getResaWithPms($idResa);
			if ($resa && $resa->numDossier && $resa->codeSite) {
				$residenceDeLogement = $this->getLogementTable()->getResidenceDeLogement($idNewLogement);
				//changement meme site
				if ($residenceDeLogement) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					$conf = $this->getConfigurationTable()->getConfig(1);
					if ($conf && $conf->bredea == 1) {
						try {
							$bredea		= null;
							if ($resa) {
								$this->initPMS($resa->idApiPms ?: 1, $idResa);

								## Traitement en fonction du PMS
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->pms) {
									if ($this->pms->getClassName() === "Bredea") {
										$bredea	= $this->pms;
									} elseif ($this->pms->getClassName() === "CeriFoyer") {
										## Rien à faire pour l'instant
									}
								}
							}
							if ($bredea) {
								if ($residenceDeLogement->idPMSResidence == $resa->codeSite) {
									//meme site
									$dateChangement = $dateChangement ? date('Ymd', strtotime($dateChangement)) : date('Ymd');
									$changementLogementWE = $conf->changementLogementWE;

									$logementNew = $this->getLogementTable()->getLogement($idNewLogement);
									$numLog = $logementNew->idPMS;
									$logementActuel = $this->getLogementTable()->getLogement($resa->idLogement);
									$numLogAncient = $logementActuel->idPMS;
									$cData = array('codeSite' => $resa->codeSite, 'numDossier' => $resa->numDossier, 'numLog' => $numLog, 'numLogAncien' => $numLogAncient, 'typre' => $resa->typre, 'dateChangement' => $dateChangement, 'pasDeFacture' => $resa->pasDeFacture, 'changementLogementWE' => $changementLogementWE, 'loyerChgtLog' => $conf->loyerChgtLog);

									$cData['dateDepart'] = $resa->dateDepart;

									if ($logementNew && $logementNew->loyer > 0) {
										$cData['loyer'] = $logementNew->loyer;
									}
									$optionsPrepFacture = array();
									if ($logementNew) {
										if ($logementNew->loyer > 0) {
											$optionsPrepFacture['loyer'] = $logementNew->loyer;
										}
										if ($conf->prestaLoyerMultiple == 1) {
											$prestaLoyerMultiple = array();
											if ($conf->prestaLoyerHC && $logementNew->loyerHC > 0) {
												$prestaLoyerMultiple[$conf->prestaLoyerHC] = $logementNew->loyerHC;
											}
											if ($conf->prestaCharges && $logementNew->charges > 0) {
												$prestaLoyerMultiple[$conf->prestaCharges] = $logementNew->charges;
											}
											if ($conf->prestaComplementLoyer && $logementNew->complementLoyer > 0) {
												$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $logementNew->complementLoyer;
											}
											if(!empty($prestaLoyerMultiple)){
												$optionsPrepFacture['prestaLoyerMultiple'] = $prestaLoyerMultiple;
											}
										}
										$cData['optionsPrepFacture'] = $optionsPrepFacture;
									}

									$modeCampagne = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
									$cData['chgLogSansMajDatesABD'] = $modeCampagne ? $modeCampagne->chgLogSansMajDatesABD : 0;

									##Recup modèle facture et loyer de la grille tarifaire
									$modeleLoyerFacture = $this->getModeleEtLoyerFacture($resa->id);
									if(!empty($modeleLoyerFacture)) {
										if(!empty($modeleLoyerFacture['loyer']) && $modeleLoyerFacture['loyer'] > 0) {
											$cData['loyer'] = $modeleLoyerFacture['loyer'];
											$cData['optionsPrepFacture']['loyer'] = $modeleLoyerFacture['loyer'];
										}
										if(!empty($modeleLoyerFacture['modeleFacture']) && $modeleLoyerFacture['modeleFacture'] != '') {
											$cData['optionsPrepFacture']['modeleFacture'] = $modeleLoyerFacture['modeleFacture'];
										}
									}

									$return = $bredea->changementLogement($cData);

									if (!empty($return) && is_array($return) && $resa->etat == 3) {
										//on supprime la ligne plannin
										$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'numLog' => $resa->numeroChambre, 'dateArrivee' => $resa->dateArrivee);
										$rep = $bredea->deleteRowFromPlanning($cData);
									}
								} else {
									//changement site : bloquer
									$return = "Vous ne pouvez pas changer le site de ce dossier";
								}
								$bredea->closeConnect();
								$this->pms = null;
							}
						} catch (\Exception $ex) {
							$return  = $ex->getMessage();
							$bredea->closeConnect();
							//echo $ex->getMessage();
						}
					}
				}
			}
		}
		return $return;
	}


	public function majresaAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");

		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$form = new ResaForm();
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$id = $request->getPost('id');
			$isAjout = "0";
			$resaExist = false;
			$isOccupe = false;
			$msgInfos = "";

			if ($id) {

				//mise a jour
				$resa = $this->getResaTable()->getListeById($id)->current();
				## on verifie si la date de depart du dossier est changer on verfie la disponibilite du nouvelle date
				if ($resa) {
					$dateDep = $request->getPost('dateDepart', null);
					$dateArr = $request->getPost('dateArrivee', null);
					if ($dateDep) {
						$dateDep = date('Y-m-d', strtotime($dateDep));
					}

					//verification date arrivet et date départ
					if ($dateDep && $dateDep != "0000-00-00" && $dateDep != "1970-01-01" && $dateArr && strtotime($dateDep) < strtotime($dateArr)) {
						$msg = "Attention date de départ inférieure à la date arrivée";
						$view = new JsonModel(array(
									'success' => false,
									'idReservation' => $id,
									'isAjout' => $isAjout,
									'msg' => $msg,
							));

						$view->setTerminal(true);
						return $view;
					}

					//var_dump($this->checkDisponibiliteLogementBredea($id,$dateDep));exit();

					if ($dateDep && $dateDep != $resa->dateDepart) {
						$isOccupe = $this->getResaTable()->checkEndDate($dateDep, $resa->idLogement, $id, array(2, 3, 7, 15), $dateArr);//false => dispo

						$isDispo = $this->checkDisponibiliteLogementBredea($id, $dateDep);

						$enTravaux = false;
						$msgTravaux = "";
						$ptl = $this->getPeriodesTravaux($resa->idLogement);
						foreach ($ptl as $pt) {
							if (strtotime($dateDep) >= strtotime($pt->dateDebutTravaux) && strtotime($dateDep) <= strtotime($pt->dateFinTravaux)) {
								$msgTravaux = "Logement ".$resa->numeroChambre." en travaux entre ".date('d-m-Y', strtotime($pt->dateDebutTravaux))." et ".date('d-m-Y', strtotime($pt->dateFinTravaux));
								$enTravaux = true;

							}
						}

						$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $dateArr, $dateDep);

						if (!$isDispo || $isOccupe || $enTravaux || $bloquerCSMsg != '') {
							if (!$isDispo) {
								$msg = "Logement non disponible pour la nouvelle date de départ $dateDep, veuillez vérifier le planning bredea";
							} elseif ($enTravaux) {
								$msg = $msgTravaux;
							} elseif ($bloquerCSMsg != '') {
								$msg = $bloquerCSMsg;
							} else {
								$msg = "Logement non disponible pour la nouvelle date de départ $dateDep";
							}
							$view = new JsonModel(array(
									'success' => false,
									'idReservation' => $id,
									'isAjout' => $isAjout,
									'msg' => $msg,
							));

							$view->setTerminal(true);
							return $view;
						}

						// Supprimer les renonces si existe
						$renonces = $this->getRdvRenonceTable()->getByIdReservations($id)->toArray();
						if (count($renonces) > 0) {
							foreach ($renonces as $key => $renonce) {
								$this->getRdvRenonceTable()->delete((int)$renonce['id']);
							}
						}

						// Supprimer Rdv si existe
						$rdv = $this->getRdvTable()->getByIdResa($id)->toArray();
						if (count($rdv) > 0) {
							$this->getRdvTable()->delete(array('idReservations' => (int)$id));
						}
					}

					// controle changement date d arrivee
					$dateArr = $request->getPost('dateArrivee');
					$dateArr = date('Y-m-d', strtotime($dateArr));
					if ($dateArr != $resa->dateArrivee) {
						$isOccupe = $this->getResaTable()->checkStartDate($dateArr, $resa->idLogement, $id, array(2, 3, 7, 15));//false => dispo

						$isDispo = $this->checkDisponibiliteLogementBredea($id, $dateArr);

						$enTravaux = false;
						$msgTravaux = "";
						$ptl = $this->getPeriodesTravaux($resa->idLogement);
						foreach ($ptl as $pt) {
							if (strtotime($dateArr) >= strtotime($pt->dateDebutTravaux) && strtotime($dateArr) <= strtotime($pt->dateFinTravaux)) {
								$msgTravaux = "Logement ".$resa->numeroChambre." en travaux entre ".date('d-m-Y', strtotime($pt->dateDebutTravaux))." et ".date('d-m-Y', strtotime($pt->dateFinTravaux));
								$enTravaux = true;

							}
						}

						$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $dateArr, $dateDep);

						if (!$isDispo || $isOccupe || $enTravaux || $bloquerCSMsg != '') {
							if (!$isDispo) {
								$msg = "Logement non disponible pour la nouvelle date de arrivée $dateArr, veuillez vérifier le planning bredea";
							} elseif ($enTravaux) {
								$msg = $msgTravaux;
							} elseif ($bloquerCSMsg != '') {
								$msg = $bloquerCSMsg;
							} else {
								$msg = "Logement non disponible pour la nouvelle date de arrivée $dateArr";
							}
							$view = new JsonModel(array(
									'success' => false,
									'idReservation' => $id,
									'isAjout' => $isAjout,
									'msg' => $msg,
							));

							$view->setTerminal(true);
							return $view;
						}
					}
					// fin controle date arrivee
				}

				if ($resa) {
					$loca = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
					if ($loca) {
						$codeGoal = $request->getPost('codeGoal');
						$codeSharepad = $request->getPost('codeSharepad');
						$upLoc = array();
						if ($codeGoal) {
							$upLoc['codeGoal'] = $codeGoal;
						}
						if ($codeSharepad) {
							$upLoc['codeSharepad'] = $codeSharepad;
						}
						if (!empty($upLoc)) {
							$this->getLocatairesTable()->updateLocataire($resa->idLocataire, $upLoc);
						}
					}
				}
				$resaOld = $this->getResaTable()->getListeById($id)->current();
				//$form->bind($loc);
				$form->setInputFilter($resa->getInputFilter());
				$form->setData($request->getPost());

				$dateResa = date('d-m-Y', strtotime($resa->dateDemandeReservation));
				$dateTimeResa = $resa->dateDemandeReservation;
				$resa->exchangeArray($request->getPost());
				//ne pas maj le typre lors de mise à jour
				if ($resaOld->typre) {
					$resa->typre = $resaOld->typre;
				}

				$resa->attestationBourse = $request->getPost('doc1Name') != "" ? $request->getPost('doc1Name') : $resa->attestationBourse;
				$resa->certificatMedical = $request->getPost('doc2Name') != "" ? $request->getPost('doc2Name') : $resa->certificatMedical;
				$resa->certificatAssur = $request->getPost('doc3Name') != "" ? $request->getPost('doc3Name') : $resa->certificatAssur;
				if (strtotime($request->getPost('dateDemandeReservation')) == strtotime($dateResa)) {
					$resa->dateDemandeReservation = $dateTimeResa;
				}

				$resa->typeLogement1 = $request->getPost('idTypeLogement1');
				$resa->typeLogement2 = $request->getPost('idTypeLogement2');
				$resa->typeLogement3 = $request->getPost('idTypeLogement3');

				//on check les date debut et fin de contrat: pas modifier une fois affecte

				if ($resaOld->numResa && $conf->modifierDatesFacturation != 1) {
					if ($resaOld->etat == 7) {
						if (strtotime($resa->dateArrivee) > strtotime($resaOld->dateArrivee)) {
							$resa->dateArriveeTheorique = $resaOld->dateArriveeTheorique;//on ne change pas
							//$msgInfos = "Date de début de contrat non modifiée";
						} elseif (strtotime($resa->dateArrivee) < strtotime($resaOld->dateArrivee)) {
							$resa->dateArriveeTheorique = $resa->dateArrivee;//on ne change pas
						}
					} else {
						$resa->dateArriveeTheorique = $resaOld->dateArriveeTheorique;
						//$msgInfos = "Date de début de contrat non modifiée";
					}
					/*Sur la date de départ si elle est dans et futur par rapport à la date initial il faut changer aussi la date de fin de contrat
					sinon on ne change que la date de départ*/
					/*if(strtotime($resa->dateDepart) <= strtotime($resaOld->dateDepart)){
						$resa->dateDepartTheorique = $resaOld->dateDepartTheorique;
					}
					/*
					correction du 04-11-2017 :
					si la date de depart est supérieur à la date de fin de facturation alors on MAJ la date de fin de facturation
					*/
					if ($resa->dateDepart && strtotime($resa->dateDepart) != strtotime($resaOld->dateDepart)) {
						if (strtotime($resa->dateDepart) <= strtotime($resaOld->dateDepartTheorique)) {
							$resa->dateDepartTheorique = $resaOld->dateDepartTheorique;//on change pas de date
							//$msgInfos = "Date de fin de contrat non modifiée car non autorisée";
						} else {
							//on change la date fin de facturation
							$resa->dateDepartTheorique = $resa->dateDepart;

							// changement de flags notification caf
							$resa->cafChangementDateDepartTheorique = '1';
						}
					}
				}

				if ($resa->dateDepart && strtotime($resa->dateDepart) != strtotime($resaOld->dateDepart)) {
					## Modification de l'etat de la résa en parti
					$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
					if($modeCamp && $modeCamp->majEtatResaEnParti == 1) {
						if(strtotime($resa->dateDepart) <= strtotime(date('Y-m-d'))) {
							$resa->etat = 6;
						}
					}
				}

				/*if($resaOld->etat != 7){
					$resa->pasDeFacture = 1;
				}*/
				$this->getResaTable()->majResa($resa);
				$idReservation = $resa->id;
				## maj dates initiales
				$upDataResa = array();
				if($conf->modifierDateArriveeDemande == 1) {
					$dateArrDem = $request->getPost('dateArriveeDemande', '');
					if($dateArrDem && substr($dateArrDem, 0, 2) != '00') {
						$dateArrDem = date('Y-m-d', strtotime($dateArrDem));
						if($dateArrDem != $resaOld->dateArriveeDemande) {
							$upDataResa['dateArriveeDemande'] = $dateArrDem;
						}
					}
				}
				if($conf->modifierDateDepartDemande == 1) {
					$dateDepDem = $request->getPost('dateDepartDemande', '');
					if($dateDepDem && substr($dateDepDem, 0, 2) != '00') {
						$dateDepDem = date('Y-m-d', strtotime($dateDepDem));
						if($dateDepDem != $resaOld->dateDepartDemande) {
							$upDataResa['dateDepartDemande'] = $dateDepDem;
						}
					}
				}

				if(!empty($upDataResa)) {
					$this->getTableObjet('reservations')->update($upDataResa, array('id' => $resa->id));
				}
				//maj programme locataire
				$progLocaToMaj = array();
				if ($resa->idProgRes) {
					$progLocaToMaj['idProgramme'] = $resa->idProgRes;
				}
				if ($resa->idSousProgRes) {
					$progLocaToMaj['idSousProgramme'] = $resa->idSousProgRes;
				}

				//maj login et pwd
				$login = $request->getPost('login');
				$password = $request->getPost('password');
				if ($login) {
					$progLocaToMaj['login'] = trim($login);
				}
				if ($password) {
					$progLocaToMaj['password'] = trim($password);
				}

				if (!empty($progLocaToMaj)) {
					$this->getTableObjet('locataires')->update($progLocaToMaj, array('id' => $resa->idLocataire));
				}

				## recalculation des prestation calculé
				$this->getPrestaTable()->calculerPrestationsDeResa($resa->id);
			} else {
				## ajout resa
				$isAjout = "1";
				$idLogement = $request->getPost('idLogement');
				$idCampagne = $request->getPost('idCampagne');
				$idLocataire = $request->getPost('idLocataire');

				$dateArrivee = $request->getPost('dateArrivee');
				$dateArrivee = date('Y-m-d', strtotime($dateArrivee));
				$dateDepart = $request->getPost('dateDepart');
				$dateDepart = date('Y-m-d', strtotime($dateDepart));

				//bug resa creer plusiseurs fois : on verifie si on a deja une résa avec meme logement, loc, dateArrivee, dateDepart
				$resa = $this->getResaTable()->getResaBy(array('idLocataire' => $idLocataire, 'idLogement' => $idLogement, 'dateArrivee' => $dateArrivee, 'dateDepart' => $dateDepart))->current();
				## on verifie aussi la disponibilite, si on autorise pas de la creer quand meme
				$create = $request->getPost('create');
				if ($create != '1') {
					$isOccupe = $this->getResaTable()->checkDisponibilite($dateArrivee, $dateDepart, $idLogement);//false => dispo
				}

				if (!$resa && !$isOccupe) {
					$logement = $this->getLogementTable()->getLogement($idLogement);
					$resa = new Resa();
					$resa->id = 0;

					$loc = $this->getLocatairesTable()->getLocataire($idLocataire);

					//ajout logein et pwd
					$login = $request->getPost('login');
					$password = $request->getPost('password');
					$upLoc = array();
					if ($login) {
						$upLoc['login'] = trim($login);
					}
					if ($password) {
						$upLoc['password'] = trim($password);
					}

					if (!empty($upLoc)) {
						$this->getLocatairesTable()->updateLocataire($idLocataire, $upLoc);
					}

					$resa->exchangeArray($request->getPost());

					$dateDemandeReservation = $request->getPost('dateDemandeReservation');
					if (!$dateDemandeReservation) {
						$resa->dateDemandeReservation = date('Y-m-d H:i:s');
					}

					if (!$resa->etat) {
						$resa->etat = 3;
					}
					//print_r($resa);exit();


					//$resa->idLogement = $request->getPost('idLogement');
					//$resa->dateArrivee = $request->getPost('dateArrivee');
					//$resa->dateDepart = $request->getPost('dateDepart');
					//$resa->dateDemandeReservation = date('d-m-Y H:i:s');
					//$resa->idLocataire = $idLocataire;
					$resa->idProgramme = $loc->idProgramme;
					$resa->idSousProgramme = $loc->idSousProgramme;
					$resa->idTypeLogement = $logement->idTypeLogement;
					$resa->typeLogement1 = $logement->idTypeLogement;
					$resa->typeLogement2 = $logement->idTypeLogement;
					$resa->typeLogement3 = $logement->idTypeLogement;
					$resa->numeroChambre = $logement->numero;
					//$resa->etat = $request->getPost('etat');
					$resa->idCampagne = $idCampagne;

					$resa->attestationBourse = $request->getPost('doc1Name');
					$resa->certificatMedical = $request->getPost('doc2Name');
					$resa->certificatAssur = $request->getPost('doc3Name');

					//$idReservation = $request->getPost('idReservation');
					//if(!$idReservation){
					$idReservation = $this->getResaTable()->majResa($resa);
					## maj de l etat du logement en occuper
					//$this->getLogementTable()->updateLogement(array('idEtat'=>'4'),array('id'=>$idLogement));
					//}
				} elseif ($resa) {
					$resaExist = true;
					$idReservation = $resa->id;
				}
			}

			if ($isOccupe) {
				$nomLog = $request->getPost('numeroChambre');
				$dateDebut = date('d-m-Y', strtotime($isOccupe->dateArrivee));
				$dateFin = date('d-m-Y', strtotime($isOccupe->dateDepart));
				$loca = $this->getLocatairesTable()->getLocataire($isOccupe->idLocataire);
				$etatResa = $this->getTableObjet('etat_reservation')->select(array('id' => $isOccupe->etat))->current();
				$msg = "Attention il y a déjà la réservation de ".trim($loca->nom).' '.trim($loca->prenom)." du $dateDebut, $dateFin sur le logement
				$nomLog dans l etat ".$etatResa->nom.", voulez-vous vraiment créer cette réservation ?";
				$view = new JsonModel(array(
						'success' => true,
						'idReservation' => $id,
						'isAjout' => $isAjout,
						'msg' => $msg,
				));

				$view->setTerminal(true);
				return $view;
			}

			## maj des choix
			$maxChoix = $request->getPost('maxChoix');
			if ($maxChoix) {
				for ($i = 1; $i <= $maxChoix; $i++) {
					$idTypeLogement = $request->getPost('idTypeLogement'.$i);
					if ($idTypeLogement) {
						$choixRow = $this->getChoixTable()
									->fetchBy(array('idReservation' => $idReservation,
													//'idTypeLogement'=>$idTypeLogement,
													'numeroChoix' => $i,
													))
									->current();
						$choix = new Choix();
						$choix->idReservation = $idReservation;
						$choix->idTypeLogement = $idTypeLogement;
						$choix->numeroChoix = $i;
						if (!$choixRow) {
							$choix->id = 0;
						} else {
							$choix->id = $choixRow->id;
						}
						$this->getChoixTable()->saveChoix($choix);
					}
				}
			}


			if ($isAjout == '1' && !$resaExist) {
				## Ajout dans Bredea
				$this->creerDossierBredea($idReservation);
			} else {
				##MAJ BREDEA
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idReservation");
				$this->updateResaPmsAndSig($idReservation);
			}

			$log = new Logs();
			if ($isAjout == '1' && !$resaExist) {
				$log->operation = "BO : Ajout nouvelle reservation , idReservation : ".$resa->id;
				$log->dataBefore = array();
				$log->dataAfter = $resa;
			} else {
				$resa = $resaOld = $this->getResaTable()->getListeById($resa->id)->current();
				$log->operation = "BO : Update fiche reservation , idReservation : ".$resa->id;
				$diff = $log->arrayDiff($resaOld, $resa);
				$log->dataBefore = $diff['before'];
				$log->dataAfter = $diff['after'];
			}
			$log->idReservation = $resa->id;
			$log->idLocataire = $resa->idLocataire;
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->tableName = "Reservations";

			if(!empty($log->dataBefore) || !empty($log->dataAfter)) {
				$this->getLogsTable()->saveLogs($log);
			}

			/*$tablePile = new Tables('pile',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$dansLaPile = $tablePile->getTable()->select(array('idReservation'=>$id))->current();

			if(!$dansLaPile){
				//ajout dans pile
				$pile = new Pile();
				$data['idReservation'] = $id;
				$data['idLocataire'] = $resa->idLocataire;
				$data['flag'] = "reservation";
				$pile->exchangeArray($data);
				$this->getPileTable()->empile($pile);
			}*/

			$view = new JsonModel(array(
						'success' => true,
						'idReservation' => $id,
						'isAjout' => $isAjout,
						'msg' => "",
						'msgInfos' => $msgInfos,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function checkInGroupe($data = array())
	{
		$idResa = (int) $data['idResa'];
		$etat = (int) $data['etat'];
		$dateArrivee = $data['dateArrivee'];
		$idGroupeResa = (int) $data['idGroupeResa'];
		$msg = "";

		$dateArrivee = $dateArrivee ? date('Y-m-d', strtotime($dateArrivee)) : null;

		//on recupere toutes les resa du groupeResa
		$resas =  $this->getResaTable()->getResaBy(array('idGroupeResa' => $idGroupeResa));
		foreach ($resas as $resa) {
			$idResa = $resa->id;
			if ($dateArrivee && strtotime($dateArrivee) != strtotime($resa->dateArrivee) && $resa->etat != $etat) {

				//$isOccupe = $this->getResaTable()->checkStartDate($dateArrivee,$resa->idLogement,$idResa);//true=>occupee, false=> free

				$isOccupe = $this->getResaTable()->checkDisponibilite($dateArrivee, $resa->dateDepart, $resa->idLogement);//false => dispo

				if ($isOccupe && $isOccupe->id != $idResa) {
					$msg = "Logement non disponible pour la date $dateArrivee";
				}
			}
		}

		$resas =  $this->getResaTable()->getResaBy(array('idGroupeResa' => $idGroupeResa));
		foreach ($resas as $resa) {
			if ($resa->etat != $etat) {
				$upData = array();
				$idResa = $resa->id;
				if ($msg == "") {
					if ($dateArrivee && strtotime($dateArrivee) != strtotime($resa->dateArrivee)) {
						$upData = array('etat' => $etat, 'dateArrivee' => $dateArrivee);
					} else {
						$upData = array('etat' => $etat);
					}

					$this->getResaTable()->updateResa($upData, array('id' => $idResa));

					//maj de l'etat de logement en occupe => 4
					$this->getLogementTable()->updateLogement(array('idEtat' => 4), array('id' => $idLogement));
				}
			}
		}

		return $msg;
	}

	private function getModePaiementCampagne($idCampagne)
	{
		$campagneType = $this->getCampagneTable()->getCampagneType($idCampagne);
		$modeValidationCamp = $this->getCampagneTable()->getCampagneMode($idCampagne);
		$modeValidationDemande = $modeValidationCamp ? $modeValidationCamp->modeValidationDemande : "";
		if ($modeValidationDemande == 2 && (!$campagneType || ($campagneType && $campagneType->code != 'cs' && $campagneType->code != 'dp'))) {
			$mode = 'paiementDirect';
		}
		return $mode;
	}

	public function checkinCpAction()
	{
		return "a";
		$fromApiControllerTablet = false;
		$params	= $this->getEvent()->getRouteMatch()->getParam('params');
		if (count($params) > 0) {
			var_dump($params);
			die();
			$fromApiControllerTablet = true;
		}

		var_dump("expressioeeeeeen");
		die();
	}

	public function checkinAction($posted = array())
	{
		$request = $this->getRequest();

		$fromApiControllerTablet = false;
		if (count($posted) > 0) {
			$fromApiControllerTablet = true;

			$this->serviceLocator = $posted['sl'];

			// $adapter = $posted['sl']->get('Zend\Db\Adapter\Adapter');
			$gestId = $posted['gestId'];

			// var_dump($gestId);die();
			// var_dump($posted['sl']->get('Zend\Db\Adapter\Adapter'));die();
		}

		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$clesTable = $this->getTableObjet('cles');
		$clesToResasTable = $this->getTableObjet('clesToResas');
		$clesToLogementTable = $this->getTableObjet('clesToLogements');
		$clesToZonesTable = $this->getTableObjet('clesToZones');
		$locatairesTable = $this->getTableObjet('locataires');
		$resasTable = $this->getTableObjet('reservations');

		if (!$fromApiControllerTablet) {
			$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
		}

		if ($request->isXmlHttpRequest() || $fromApiControllerTablet) {
			// var_dump($fromApiControllerTablet);die();
			if ($fromApiControllerTablet) {
				$idResa = $posted['idResa'];

				$resa = $this->getTableObjet('reservations')
				->select(array('id' => $idResa))->current();
				$loc = $this->getTableObjet('reservations')
				->select(array('id' => $resa->idLocataire))->current();

				$etat = $resa->etat;
				$dateArrivee = $resa->dateArrivee;
				$dateArriveeTheorique = $resa->dateArriveeTheorique;
				$telephoneMobile = $loc->telephoneMobile;
				$genererAttestHeb = 0;
				$generercontratHeb = 0;
				$lang = $loc->langue;
				$ids = [];
				$peripherique = false;
				$zones = [];
				$numeroEncodeur = [];
				$checkinAll = false;
			} else {
				$idResa = (int) $request->getPost('idResa');
				$etat = (int) $request->getPost('etat');
				$dateArrivee = $request->getPost('dateArrivee');
				$genererAttestHeb = $request->getPost('attestHeb');
				$generercontratHeb = $request->getPost('contratHeb');
				$lang = $request->getPost('lang');
				$checkinAll = $request->getPost('checkinAll');//check in tout le groupe
				$ids = $request->getPost('ids');//checkin en masse
				$dateArriveeTheorique = $request->getPost('dateArriveeTheorique');
				$dateArriveeTheorique = $dateArriveeTheorique ? date('Y-m-d', strtotime($dateArriveeTheorique)) : null;
				$telephoneMobile = $request->getPost('telephoneMobile', '');
				$peripherique = $request->getPost('peripherique', '');
				$zones = $request->getPost('zones') ? $request->getPost('zones') : [];
				$numeroEncodeur = $request->getPost('numeroEncodeur', '');

				$factureManuelle = $request->getPost('factureManuelle', 0);
				$idsPrestations = $request->getPost('idsPrestations', array());
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa etat=$etat dateArrivee=$dateArrivee genererAttestHeb=$genererAttestHeb generercontratHeb=$generercontratHeb checkinAll=$checkinAll ids=".json_encode($ids));


			$conf = $this->getConfigurationTable()->getConfig(1);

			// var_dump($conf);die();

			$resaIds = array();
			if (!empty($ids)) {
				$resaIds = $ids;
			} elseif ($idResa) {
				// On maj le téléphone du locataire que si checkIn un par un.
				$reservation =  $this->getResaTable()->getResa($idResa);
				if (trim($telephoneMobile)) {
					$locatairesTable->update(array('telephoneMobile' => $telephoneMobile), array('id' => (int) $reservation->idLocataire));
				}
				$resaIds[] = $idResa;
			}

			$dateArrivee = $dateArrivee ? date('Y-m-d', strtotime($dateArrivee)) : null;

			$now = date('Y-m-d');

			$date_format = explode("-", $dateArrivee);
			$var_day_debut = $date_format[2];
			$var_month_debut = $date_format[1];
			$var_year_debut = $date_format[0];

			$isSerrures = false;
			if ($peripherique && $numeroEncodeur) {
				$dataEncodeSerrures = array(
					'peripherique' => $peripherique,
					'type' => 'p',
					'numeroEncodeur' => $numeroEncodeur,
					'zones' => $zones,
					'startDateTime' => str_replace(':', '', date('H:i').$var_day_debut.$var_month_debut.substr($var_year_debut, 2)),
					'expiringDateTime' => '',
				);
				$sessSerrures = new Container('serrures');
				$sessSerrures->numeroEncodeur = $numeroEncodeur ? $numeroEncodeur : '1';
				$isSerrures = true;
			}
			$msgErreur = "";
			$tableLogement = $this->getTableObjet('logements');
			$tableComptes = $this->getTableObjet('comptes');
			foreach ($resaIds as $idResa) {
				$resa = $this->getResaTable()->getResaWithPms($idResa);
				$locataire = $locatairesTable->select(array('id' => (int) $resa->idLocataire))->current();

				$idLogement = $resa->idLogement;
				$sansLogement = false;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa etat=$etat idLogement=$idLogement idPMS=".$resa->idPMS." numDossier=".$resa->numDossier." numResa=".$resa->numResa." idGroupeResa=".$resa->idGroupeResa);

				$modePaiementCampagne = $this->getModePaiementCampagne($resa->idCampagne);

				if (($modePaiementCampagne == 'paiementDirect' && $resa->numDossier) || ($conf->encaisAcompte == 1 && !$resa->numDossier) && (!$resa->idGroupeResa && $resa->codeSite && $resa->numResa)) {
					//getResaiLogement
					//on verfifie si la resai a un logement, si oui, on passe en dossier, sinon on affiche un msg d'erreur
					if ($conf && $conf->bredea == 1) {
						try {
							$bredea		= null;
							if ($resa) {
								$this->initPMS($resa->idApiPms ?: 1, $idResa);

								## Traitement en fonction du PMS
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->pms) {
									if ($this->pms->getClassName() === "Bredea") {
										$bredea	= $this->pms;
									} elseif ($this->pms->getClassName() === "CeriFoyer") {
										## Rien à faire pour l'instant
									}
								}
							}
							if ($bredea) {
								##viaPMS $bredea = new BredeaSql();
								$logementResai = $bredea->getResaiLogement($resa->numResa, $resa->codeSite);
								if (!empty($logementResai) && !empty($logementResai['numeroChambre'])) {
									$log_code = $logementResai['numeroChambre'];
									// on maj le idLogement de la résa
									$dossierCreer = false;
									if (!$idLogement) {
										$select = $tableLogement->getSql()->select();
										$select->join('batiments', 'batiments.id = logements.idBatiment', array('idBatiment' => 'id'));
										$select->join('residences', 'residences.id = batiments.idResidence', array('idResidence' => 'id'));
										$select->where(array('residences.idPMS' => $resa->codeSite, 'logements.numero' => $log_code));
										$loge = $tableLogement->selectWith($select)->current();
										if ($loge) {
											$resaUpData = array();
											$resaUpData['idLogement'] = $loge->id;
											$resaUpData['numeroChambre'] = $loge->idPMS;
											$resaUpData['idTypeLogementAttribue'] = $loge->idTypeLogement;
											$this->getResaTable()->updateResa($resaUpData, array('id' => $idResa));

											$ret = $this->passerEnDossierBredea($idResa);
											if ($ret) {
												$resa =  $this->getResaTable()->getResa($idResa);
												$idLogement = $resa->idLogement;
												$dossierCreer = true;
											} else {
												$msgErreur .= $resa->id." Erreur creation dossier bredea<br>";
											}
										} else {
											$msgErreur .= $resa->id." Logement $log_code non trouvé sur WL<br>";
										}
									} elseif (!$resa->numDossier) {
										$ret = $this->passerEnDossierBredea($idResa);
										if ($ret) {
											$resa =  $this->getResaTable()->getResa($idResa);
											$idLogement = $resa->idLogement;
											$dossierCreer = true;
										} else {
											$msgErreur .= $resa->id." Erreur creation dossier bredea<br>";
										}
									} elseif ($resa->numDossier) {
										$dossierCreer = true;
									}

									// ajout controle si pas d OD deja créer, pour ne pas creer de doublons
									$ODCreer = $this->checkODCompte($idResa);//true si creer, et false pas creer

									if ($dossierCreer && !$ODCreer) {
										## on cree la facture FDD
										$fraisResa = array();
										$comptes = $tableComptes->select(array('idReservation' => $idResa));
										if ($comptes->count() > 0) {
											$noFact = $this->creerFactureFRAIS($idResa, 'acompte');

											$log = new Logs();
											$log->dateOperation = date('Y-m-d H:i:s');
											$log->idGestionnaire = 0;
											$log->operation = "CheckIN creation facture FDD de résa $idResa";
											$log->dataBefore = array();
											$log->dataAfter = array('noFact' => $noFact);
											$log->tableName = "Bredea";
											$log->idLocataire = $resa->idLocataire;
											$log->idReservation = $resa->id;
											$this->getLogsTable()->saveLogs($log);

											$this->creationODCompte($idResa);
											$this->creationODAcompteCaution($idResa);
										}
									}
								} else {
									$sansLogement = true;
								}
								$bredea->closeConnect();
								$this->pms	= null;
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
							echo $ex->getMessage();
						}
					}
				}

				## controle date arrivée : si dans le futuren ne pas faire le checkIn
				if(($resa->idGroupeResa && $checkinAll == 1) || $resa->idLogement){
					$dateArr=($dateArrivee && strtotime($dateArrivee) != strtotime($resa->dateArrivee)) ? $dateArrivee : $resa->dateArrivee;
					if($dateArr && (strtotime($dateArr) > strtotime($now)))  {
						$msgErreur .= "Date arrivée dans le future pour la réservation ".$resa->id."<br>";
						continue;
					}
				}

				$msg = $etatTXT = "";
				$confirmed = false;
				$lienDoc = $lienDoc2 = "";
				$lienDocEN = $lienDoc2EN = "";

				$msgGroupe = "";
				$idGroupeResa = "";
				if ($resa->idGroupeResa && $checkinAll == 1) {
					$idGroupeResa = $resa->idGroupeResa;
					$post = $request->getPost();
					$post['idGroupeResa'] = $resa->idGroupeResa;
					$msgGroupe = $this->checkInGroupe($post);
					$etatResa = $this->getTable('etat_reservation')->select(array('id' => $etat))->current();
					$etatTXT = $etatResa ? $etatResa->nom : "";
					if ($msgGroupe) {
						$msg = $msgGroupe;
					} else {
						$confirmed = true;
						$msg = "Validation bien faite.";

						$log = new Logs();
						$diff = $log->arrayDiff($resa, $this->getResaTable()->getResa($idResa));
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "Réservation : checkIn ".$resa->numeroChambre;
						$log->dataBefore = $diff['before'];
						$log->dataAfter = $diff['after'];
						$log->tableName = "reservations";
						$log->idReservation = $idResa;
						$log->idLocataire = $resa->idLocataire;
						$this->getLogsTable()->saveLogs($log);
					}
				} elseif ($idLogement) {
					if ($dateArrivee && strtotime($dateArrivee) != strtotime($resa->dateArrivee)) {
						$isOccupe = $this->getResaTable()->checkStartDate($dateArrivee, $idLogement, $idResa, array(2, 3, 7, 15));//true=>occupee, false=> free
						$campagneResaToChange	= $this->getCampagneTable()->getCampagneType($resa->idCampagne);
						if ($campagneResaToChange && $campagneResaToChange->code == 'cs') {
							$checkStartEndDates	= $this->getResaTable()->checkStartEndDates($adapter, $idResa, $dateArrivee, $resa->dateDepart);
							if ($checkStartEndDates != 0) {
								## Erreur de date -> hors campagne
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$msg = "Impossible de changer la date d'arrivée hors campagne";
							}
						}

						if (!$msg) {
							if ($isOccupe) {
								$msg = "Logement non disponible pour la date $dateArrivee";
							} else {
								$upData = array('etat' => $etat, 'dateArrivee' => $dateArrivee);
								/*
								Et pour le check-in si la date est ds le passé par rapport a la date prevu on change les deux mais si la date est ds le futur on ne change que la date d'arrivée
								*/
								$upData['dateArriveeTheorique'] = $resa->dateArrivee;
								if (strtotime($dateArrivee) < strtotime($resa->dateArrivee)) {
									//on change aussi dateArriveeTheorique
									$upData['dateArriveeTheorique'] = $dateArrivee;
								} elseif ($dateArriveeTheorique) {
									$upData['dateArriveeTheorique'] = $dateArriveeTheorique;
								}

								$confirmed = true;
							}
						}
					} else {
						$upData = array('etat' => $etat);
						if ($dateArriveeTheorique) {
							$upData['dateArriveeTheorique'] = $dateArriveeTheorique;
						}
						$confirmed = true;
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa dateArrivee=$dateArrivee confirmed=$confirmed");

					if ($confirmed) {
						$modeCampagne = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if($modeCampagne && $modeCampagne->nePasMajPasDeFacture == 2){
							$upData['pasDeFacture'] = 1;
						}else{
							$upData['pasDeFacture'] = 0;
						}
						$this->getResaTable()->updateResa($upData, array('id' => $idResa));
						$etatResa = $this->getTable('etat_reservation')->select(array('id' => $etat))->current();
						$etatTXT = $etatResa ? $etatResa->nom : "";

						## update bredea
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");
						$this->updateResaPmsAndSig($idResa);

						//maj de l'etat de logement en occupe => 4
						$this->getLogementTable()->updateLogement(array('idEtat' => 4), array('id' => $idLogement));

						##BREDEA
						if ($conf && $conf->bredea == 1) {
							try {
								$resa =  $this->getResaTable()->getResaWithSig($idResa); ## Remonte aussi les infos de PMS
								$bredea		= null;
								if ($resa->idPMS || $resa->numDossier) {
									$this->initPMS($resa->idApiPms ?: 1, $idResa);

									## Traitement en fonction du PMS
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($this->pms) {
										if ($this->pms->getClassName() === "Bredea") {
											$bredea	= $this->pms;
										} elseif ($this->pms->getClassName() === "CeriFoyer") {
											$this->pms->checkIn($resa);
										}
									}
								}
								if ($bredea) {
									##viaPMS $bredea = new BredeaSql();

									//dateArrivee,numDoss,codeSite
									//$residence = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);
									$cData = array();
									$cData['numDoss'] = $resa->numDossier;
									$cData['dateArrivee'] = $resa->dateArrivee ? date('Ymd', strtotime($resa->dateArrivee)) : '0';
									$cData['dateArriveeTheorique'] = $upData['dateArriveeTheorique'] ? date('Ymd', strtotime($upData['dateArriveeTheorique'])) : $cData['dateArrivee'];
									if ($resa->codeSite) {
										//on recupere lo logement
										$log = $this->getLogementTable()->getLogement($idLogement);
										$cData['codeLog'] = $resa->numeroChambre;
										if ($conf->mode == "HEC") {
											if ($log->idTypeLogement == 1) {
												//confort individuel
												$cData['confort'] = 1;
												$this->miseEnSommeilWL('confort', $idLogement, 1);
											} elseif ($log->idTypeLogement == 5) {
												//co-chambre
												$cData['coChambre'] = 1;
												$this->miseEnSommeilWL('coChambre', $idLogement, 1);
											}
										}

										$optionsPrepFacture = array();
										if ($log) {
											if ($log->loyer > 0) {
												$optionsPrepFacture['loyer'] = $log->loyer;
											}
											if ($conf->prestaLoyerMultiple == 1) {
												$prestaLoyerMultiple = array();
												if ($conf->prestaLoyerHC && $log->loyerHC > 0) {
													$prestaLoyerMultiple[$conf->prestaLoyerHC] = $log->loyerHC;
												}
												if ($conf->prestaCharges && $log->charges > 0) {
													$prestaLoyerMultiple[$conf->prestaCharges] = $log->charges;
												}
												if ($conf->prestaComplementLoyer && $log->complementLoyer > 0) {
													$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $log->complementLoyer;
												}
												if(!empty($prestaLoyerMultiple)){
													$optionsPrepFacture['prestaLoyerMultiple'] = $prestaLoyerMultiple;
												}
											}
											$cData['optionsPrepFacture'] = $optionsPrepFacture;
										}

										##Recup modèle facture et loyer de la grille tarifaire
										$modeleLoyerFacture = $this->getModeleEtLoyerFacture($resa->id);
										if(!empty($modeleLoyerFacture)) {
											if(!empty($modeleLoyerFacture['loyer']) && $modeleLoyerFacture['loyer'] > 0) {
												$cData['loyer'] = $modeleLoyerFacture['loyer'];
												$cData['optionsPrepFacture']['loyer'] = $modeleLoyerFacture['loyer'];
											}
											if(!empty($modeleLoyerFacture['modeleFacture']) && $modeleLoyerFacture['modeleFacture'] != '') {
												$cData['optionsPrepFacture']['modeleFacture'] = $modeleLoyerFacture['modeleFacture'];
											}
										}

										if($modeCampagne) $cData['nePasMajPasDeFacture'] = $modeCampagne->nePasMajPasDeFacture;

										$cData['codeSite'] = $resa->codeSite;
										$cData['typre'] = $resa->typre;
										$cData['loyer'] = $log->loyer ? $log->loyer : 0;
										$cData['typeFacturation'] = $conf->typeFacturation;
										$cData['dateDebutFact'] = $conf->dateDebutFact;
										$return = $bredea->check_in($cData);
										//on maj les dates theorique
										$upData = array();
										if (!empty($return['dateArriveeTheorique'])) {
											$upData['dateArriveeTheorique'] = date('Y-m-d', strtotime($return['dateArriveeTheorique']));
										}
										if (!empty($return['dateDepartTheorique'])) {
											$upData['dateDepartTheorique'] = date('Y-m-d', strtotime($return['dateDepartTheorique']));

											// changement de flags notification caf
											$upData['cafChangementDateDepartTheorique'] = '1';
										}

										if (!empty($upData)) {
											$this->getResaTable()->updateResa($upData, array('id' => $idResa));
										}
									}
									$bredea->closeConnect();
									$this->pms	= null;
									$this->majDatesTheoriques($idResa);
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
								echo $ex->getMessage();
							}
							try {
								if ($genererAttestHeb == 1) {
									// on génrèe l'attest d'hébergement : id 6
									if (in_array('FR', $lang)) {
										$lienDoc = $this->genererModeleDocument($idResa, "", 6);
									}
									if (in_array('EN', $lang)) {
										$lienDocEN = $this->genererModeleDocument($idResa, "", 6, array('lang' => 'EN'));
									}
								}
								if ($generercontratHeb == 1) {
									// on génrèe contrat l'attest d'hébergement : id 8
									if (in_array('FR', $lang)) {
										$lienDoc2 = $this->genererModeleDocument($idResa, "", 8);
									}
									if (in_array('EN', $lang)) {
										$lienDoc2EN = $this->genererModeleDocument($idResa, "", 8, array('lang' => 'EN'));
									}
								}

								## envois de mail checkin
								$isPermanent = $this->getResaTable()->isPermanent($resa->idLocataire);
								//ne pas envoyer le mail checkin si permanent meme chambre
								// $idResa, $type=0, $idModele = 0, $options=array()
								if (!$isPermanent) {
									$this->envoyerMail($idResa, 16, 0, array('fromTabletteEdl' => true));
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
								echo $ex->getMessage();
							}
						}
						if ($resa->idApiSig && $resa->idReservationSig) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." idReservationSig=".$resa->idReservationSig);
							try {
								$this->initSIG($resa->idApiSig ?: 1, $resa->id);

								## Traitement en fonction du SIG
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->sig) {
									$this->sig->checkinResa($resa);
								} else {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." Impossible d'initialiser le SIG");
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
								## On continue quand même normalement
							}
						}

						##FIN BREDEA

						$msg = "Validation bien faite.";
						##Facturation checkin
						if ($factureManuelle == 1 && !empty($idsPrestations)) {
							$prestations = array();
							foreach ($idsPrestations as $pRow) {
								$idPrestation = $pRow['idPrestation'];
								$montantPrestation = $pRow['montantPrestation'];
								$prest = $this->getPrestaTable()->getPrestation($idPrestation);
								if ($prest) {
									if ($montantPrestation) {
										$prest->montant = $montantPrestation;
										$prest->montantPrestation = $montantPrestation;
									} else {
										$prest->montantPrestation = $prest->montant;
									}
									$prestations[] = $prest;
								}
							}
							if (!empty($prestations)) {
								$noFact = $this->creerPrestaFacture($idResa, 'checkin', array('prestations' => $prestations));
								if ($noFact) {
									$msg .= "<br />Facture $noFact bien créée";
								}
							}
						}


						$log = new Logs();
						$diff = $log->arrayDiff($resa, $this->getResaTable()->getResa($idResa));
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "Réservation : checkIn ".$resa->numeroChambre;
						$log->dataBefore = $diff['before'];
						$log->dataAfter = $diff['after'];
						$log->tableName = "reservations";
						$log->idReservation = $idResa;
						$log->idLocataire = $resa->idLocataire;
						$this->getLogsTable()->saveLogs($log);

						if ($isSerrures) {
							// On autorise le checkIn serrures
							$clesData = array(
								'nom' => $locataire->nom,
								'prenom' => $locataire->prenom,
								'telephone' => $locataire->telephoneMobile,
								'dateDebutValidite' => $dateArrivee,
								'dateFinValidite' => $resa->dateDepart ? $resa->dateDepart : date('Y-m-d', strtotime('+1 years')).' 00:00:00',
								'type' => 'p', // par default c'est une clé principale
								'peripherique' => $peripherique,
								'active' => '1',
							);
							$clesTable->insert($clesData);
							$idClesInserted = $adapter->getDriver()->getLastGeneratedValue();

							// On insère le logement par défault
							$clesToLogementTable->insert(array('idCles' => $idClesInserted, 'idLogement' => $resa->idLogement));

							// On insère clesToResas
							$clesToResasTable->insert(array('idCles' => $idClesInserted, 'idResa' => $idResa));

							// On insère les zones
							if (count($zones) > 0) {
								foreach ($zones as $key => $zone) {
									$clesToZonesTable->insert(array('idCles' => $idClesInserted, 'idZones' => $zone['id']));
								}
							}


							// Si et seulement si le type de peripherique est encodeur
							if ($peripherique === 'encodeur') {
								$date_format = explode("-", $resa->dateDepart);
								$var_day_fin = $date_format[2];
								$var_month_fin = $date_format[1];
								$var_year_fin = $date_format[0];
								$dataEncodeSerrures['expiringDateTime'] = '0059'.$var_day_fin.$var_month_fin.substr($var_year_fin, 2);
								$this->encodeSerrures($dataEncodeSerrures);
							}
						}//end if isSerrures
					}
				} else {
					if ($sansLogement) {
						$msgErreur .= "Aucun logement attribué sur bredea à la réservation ".$resa->id."<br>";
					} else {
						$msgErreur .= "Aucun logement attribué à la réservation ".$resa->id."<br>";
					}
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						'etat' => $etatTXT,
						'idResa' => $idResa,
						'msg' => $msg,
						'confirmed' => $confirmed,
						'lienDoc' => $lienDoc,
						'lienDoc2' => $lienDoc2,
						'lienDocEN' => $lienDocEN,
						'lienDoc2EN' => $lienDoc2EN,
						'idGroupeResa' => $idGroupeResa,
						'msgErreur' => $msgErreur,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function checkOutGroupe($data = array())
	{
		$idResa = (int) $data['idResa'];
		$etat = (int) $data['etat'];
		$dateDepart = $data['dateDepart'];
		$dateDepart = $dateDepart ? date('Y-m-d', strtotime($dateDepart)) : null;
		$idGroupeResa = (int) $data['idGroupeResa'];
		$msg = "";


		//on recupere toutes les resa du groupeResa
		$resas =  $this->getResaTable()->getResaBy(array('idGroupeResa' => $idGroupeResa));
		foreach ($resas as $resa) {
			$idResa = $resa->id;
			if ($dateDepart && strtotime($dateDepart) != strtotime($resa->dateDepart) && $resa->etat != $etat) {

				//$isOccupe = $this->getResaTable()->checkEndDate($dateDepart,$resa->idLogement,$idResa);//true=>occupee, false=> free

				$isOccupe = $this->getResaTable()->checkDisponibilite($resa->dateArrivee, $dateDepart, $resa->idLogement);//false => dispo

				if ($isOccupe && $isOccupe->id != $idResa) {
					$msg = "Logement non disponible pour la date $dateDepart";
				}
			}
		}

		$resas =  $this->getResaTable()->getResaBy(array('idGroupeResa' => $idGroupeResa));
		foreach ($resas as $resa) {
			if ($resa->etat != $etat) {
				$upData = array();
				$idResa = $resa->id;
				if ($msg == "") {
					if ($dateDepart && strtotime($dateDepart) != strtotime($resa->dateDepart)) {
						$upData = array('etat' => $etat, 'dateDepart' => $dateDepart);
					} else {
						$upData = array('etat' => $etat);
					}

					$etatIC = $this->getPremierEtatIC();
					$upData['idIntercontrat'] = $etatIC->id;

					$this->getResaTable()->updateResa($upData, array('id' => $idResa));

					//maj de l'etat de logement en occupe => 4
					$this->getLogementTable()->updateLogement(array('idEtat' => 3), array('id' => $idLogement));
				}
			}
		}
		return $msg;
	}

	public function checkoutAction()
	{
		$request = $this->getRequest();

		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$clesTable = $this->getTableObjet('cles');
		$clesToResasTable = $this->getTableObjet('clesToResas');
		$clesToLogementTable = $this->getTableObjet('clesToLogements');
		$clesToZonesTable = $this->getTableObjet('clesToZones');
		$locatairesTable = $this->getTableObjet('locataires');
		$resasTable = $this->getTableObjet('reservations');
		$edlModeleTable = $this->getTableObjet('edl_modele');

		$conf = $this->getConfigurationTable()->getConfig(1);

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		if ($request->isXmlHttpRequest()) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : POST=".json_encode($_POST));
			$idResa = (int) $request->getPost('idResa');
			$etat = (int) $request->getPost('etat');
			$dateDepart = $request->getPost('dateDepart');
			if($dateDepart) $dateDepart = str_replace('/','-',$dateDepart);
			$dateDepart = ($dateDepart && substr($dateDepart, 0, 2) != '00') ? date('Y-m-d', strtotime($dateDepart)) : null;
			$dateDepartTheorique = $request->getPost('dateDepartTheorique');
			if($dateDepartTheorique) $dateDepartTheorique = str_replace('/','-',$dateDepartTheorique);
			$dateDepartTheorique = $dateDepartTheorique ? date('Y-m-d', strtotime($dateDepartTheorique)) : null;
			$genererAttestDep = $request->getPost('attestDep');
			$lang = $request->getPost('lang');
			$checkoutAll = $request->getPost('checkoutAll');//check out tout le groupe
			$ids = $request->getPost('ids');//checkout en masse
			$remise_des_cles = $request->getPost('remise_des_cles');//checkout en masse
			$checkoutAuto	=  $request->getPost('checkoutAuto');//checkout automatique des réservations avec date de départ dépassé
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa etat=$etat dateDepart=$dateDepart dateDepartTheorique=$dateDepartTheorique genererAttestDep=$genererAttestDep checkoutAuto=$checkoutAuto ids=".json_encode($ids));

			$typeEmailTable = $this->getTableObjet('type_email')->select(array('type' => 'Checkout'))->current();
			$checkoutMailType = $typeEmailTable ? $typeEmailTable->id : null;

			$resaIds = array();
			if ($checkoutAuto) {
				## Recherche de toutes les réservations ACCUEILLI et avec une date de départ dans le passé
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$dateDepart		= null;
				$dateDepartTheorique	= null;
				$checkoutAll		= null;

				$resas	= $this->getResaTable()->getResaBy("reservations.archive = '0' AND reservations.etat = 7 AND reservations.dateDepart is not null AND reservations.dateDepart > 1970-01-01 AND reservations.dateDepart < NOW()", false, false, ['reservations.dateDepart', 'reservations.id']);
				if ($resas) {
					$nbResas	= $resas->count();
					$ind		= 0;
					foreach ($resas as $resa) {
						$ind++;
						printf("$ind/$nbResas : idResa=%d dateArrivee=%s dateDepart=%s\n", $resa->id, $resa->dateArrivee, $resa->dateDepart);
						$resaIds[]	= $resa->id;
					}
				}
			} else {
				if (!empty($ids)) {
					$resaIds = $ids;
				} elseif ($idResa) {
					$resaIds[] = $idResa;
				}
			}

			$nbResas	= count($resaIds);
			$ind		= 0;
			if ($nbResas) {
				foreach ($resaIds as $idResa) {
					$ind	++;

					// On maj le status de remise de cles de la reservation
					$resasTable->update(array('remise_des_cles' => $remise_des_cles), array('id' => (int) $idResa));
					$resa =  $this->getResaTable()->getResa($idResa);
					$idLogement = $resa->idLogement;

					if ($checkoutAuto) {
						$dateDepart	= $resa->dateDepart;
						if (!$dateDepart) {
							printf("$ind/$nbResas : idResa=%d dateArrivee=%s dateDepart=%s : abandon\n", $resa->id, $resa->dateArrivee, $resa->dateDepart);
							continue;
						}
						printf("$ind/$nbResas : idResa=%d dateArrivee=%s dateDepart=%s\n", $resa->id, $resa->dateArrivee, $resa->dateDepart);
					}

					$msg = $etatTXT = "";
					$confirmed = false;
					$lienDoc = $lienDocEN = "";

					$msgGroupe = "";
					$idGroupeResa = "";
					if ($resa->idGroupeResa && $checkoutAll == 1) {
						$idGroupeResa = $resa->idGroupeResa;
						$post = $request->getPost();
						$post['idGroupeResa'] = $resa->idGroupeResa;
						$msgGroupe = $this->checkOutGroupe($post);

						$etatIC = $this->getPremierEtatIC();
						$etatResa = $this->getTable('etat_reservation')->select(array('id' => $etat))->current();
						$etatTXT = $etatIC->nom;

						if ($msgGroupe) {
							$msg = $msgGroupe;
						} else {
							$confirmed = true;
							$msg = "Validation bien faite.";
							if ($checkoutMailType) {
								$this->envoyerMail($resa->id, $checkoutMailType);
							}

							$log = new Logs();
							$diff = $log->arrayDiff($resa, $this->getResaTable()->getResa($idResa));
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "Réservation : checkOut ".$resa->numeroChambre;
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "reservations";
							$log->idReservation = $idResa;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
						}
					} else {
						if ($dateDepart && strtotime($dateDepart) != strtotime($resa->dateDepart)) {
							$isOccupe = $this->getResaTable()->checkEndDate($dateDepart, $idLogement, $idResa, array(2, 3, 7, 15));//true=>occupee, false=> free
							//print_r($isOccupe);
							if ($isOccupe) {
								$msg = "Logement non disponible pour la date $dateDepart";
							} else {
								$upData = array('dateDepart' => $dateDepart, 'etat' => $etat);
								$upData['dateDepartTheorique'] = $resa->dateDepart;
								if (strtotime($dateDepart) > strtotime($resa->dateDepart)) {
									//on change aussi dateDepartTheorique
									$upData['dateDepartTheorique'] = $dateDepart;

									// changement de flags notification caf
									$upData['cafChangementDateDepartTheorique'] = '1';
								}
								$confirmed = true;
							}
						} elseif(!$dateDepart && (!$resa->dateDepart || substr($resa->dateDepart, 0, 2) == '00')) {
							$msg = "Veuillez choisir une date de départ";
						} else {
							$upData = array('etat' => $etat);
							$confirmed = true;
						}

						//si date fin facturation modifiable on prend celle envoyer par le form
						if ($conf->modifierDatesFacturation == 1 && $dateDepartTheorique) {
							$upData['dateDepartTheorique'] = $dateDepartTheorique;

							// changement de flags notification caf
							$upData['cafChangementDateDepartTheorique'] = '1';
						}

						if ($confirmed) {
							## si un renouvelant on passe pas par IC si libre_type_de_renouvelant = VRMC 180 ou FRMC 182
							$passerEnIC = true;
							$locInfos = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($resa->idLocataire, $adapter, $idResa);
							if ($locInfos && array_key_exists('libre_type_de_renouvelant', $locInfos) && ($locInfos['libre_type_de_renouvelant'] == 180 || $locInfos['libre_type_de_renouvelant'] == 182)) {
								$this->getResaTable()->updateResa($upData, array('id' => $idResa));

								//on cherche sa nouvelle resa sur le meme logement
								$newResa = $this->getResaTable()->getLocNextResa($resa->idLocataire, $resa->idLogement);
								if ($newResa) {
									//on fait le sortie du meme resa
									//puis entree de la nouvelle

									// $this->validerEdlAuto($idResa,$idResa,'sortant');
									// $this->validerEdlAuto($idResa,$newResa->id);
									$passerEnIC = false;
								} else {
									// Si le modèle d'EDL est activé, on n'active pas l'intercontrat
									$edlModele = $edlModeleTable->select(array('id_logement' => (int) $resa->idLogement))->current();
									if ($edlModele && $edlModele->enabled == 1) {
										$passerEnIC = false;
									} elseif ($edlModele && $edlModele->enabled == 0) {
										$passerEnIC = true; // On peut passer en IC si c'est pas une nouvelle resa et que le modèle est désactiver (parce que le C.O se fait via API lors de l'envoie de l'EDL)
									}
								}
							}


							$isPermanent = $this->getResaTable()->isPermanent($resa->idLocataire);
							if ($isPermanent) {
								$passerEnIC = false;
							}//ne pas passer en checkout si permanent meme chambre

							$campagneType		= $this->getCampagneTable()->getCampagneType($resa->idCampagne);
							$campagneMode 		= $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
							$codeTypeCampagne	= is_object($campagneType) ? $campagneType->code : '';
							if ($campagneMode && $campagneMode->activerIntercontratCS != 1) {
								$passerEnIC	= false;
							}

							## si on a pas l'IC
							$etatICRows = $this->getEtatIntercontratTable()->select();
							if ($etatICRows->count() == 0) {
								$passerEnIC	= false;
							}
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idCampagne=".$resa->idCampagne." etat=".$resa->etat." codeTypeCampagne=$codeTypeCampagne passerEnIC=$passerEnIC");

							try {
								if ($passerEnIC) {
									//on passe la resa à la première etat IC
									$etatIC = $this->getPremierEtatIC();
									if ($etatIC->id > 0) {
										$upData['idIntercontrat'] = $etatIC->id;
									}
									if (!empty($upData)) {
										$this->getResaTable()->updateResa($upData, array('id' => $idResa));
										$etatResa = $this->getTable('etat_reservation')->select(array('id' => $etat))->current();
										$etatTXT = $etatIC->nom;

										if ($etatIC->id > 0) {
											//on ajoute l intercontrat
											$this->ajouterEtatIntercontrat($idResa, $dateDepart, "", null, $etatIC->id);

											//maj de l'etat de logement en intercontrat => 3
											$this->getLogementTable()->updateLogement(array('idEtat' => 3), array('id' => $idLogement));
										}
									}
								} elseif (!empty($upData)) {
									$this->getResaTable()->updateResa($upData, array('id' => $idResa));
									$etatResa = $this->getTable('etat_reservation')->select(array('id' => $etat))->current();
									$etatTXT = 'Disponible';
									//on met le logement en dispo
									$this->getLogementTable()->updateLogement(array('idEtat' => 1), array('id' => $idLogement));
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
							}

							## update bredea
							try {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");
								$this->updateResaPmsAndSig($idResa);
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
							}

							##BREDEA

							$conf = $this->getConfigurationTable()->getConfig(1);
							if ($conf && $conf->bredea == 1) {
								try {
									$resa =  $this->getResaTable()->getResaWithSig($idResa); ## Remonte aussi les infos de PMS
									$bredea		= null;
									if ($resa->idPMS || $resa->numDossier) {
										$this->initPMS($resa->idApiPms ?: 1, $idResa);

										## Traitement en fonction du PMS
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										if ($this->pms) {
											if ($this->pms->getClassName() === "Bredea") {
												$bredea	= $this->pms;
											} elseif ($this->pms->getClassName() === "CeriFoyer") {
												$this->pms->checkOut($resa);
											}
										}
									}
									if ($bredea) {
										##viaPMS $bredea = new BredeaSql();
										//dateArrivee,numDoss,codeSite
										//$residence = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);
										$cData = array();
										$cData['numDoss'] = $resa->numDossier;
										$cData['dateDepart'] = $resa->dateDepart ? date('Ymd', strtotime($resa->dateDepart)) : '0';
										$cData['dateFinFacturation'] = $upData['dateDepartTheorique'] ? date('Ymd', strtotime($upData['dateDepartTheorique'])) : $cData['dateDepart'];
										if ($resa->codeSite) {
											$log = $this->getLogementTable()->getLogement($idLogement);
											$cData['codeLog'] = $resa->numeroChambre;
											if ($conf->mode == "HEC") {
												if ($log->idTypeLogement == 1) {
													//confort individuel
													$cData['confort'] = 1;
													$this->miseEnSommeilWL('confort', $idLogement, 0);
												} elseif ($log->idTypeLogement == 5) {
													//co-chambre
													$cData['coChambre'] = 1;
													$this->miseEnSommeilWL('coChambre', $idLogement, 0);
												}
											}
											$cData['codeSite'] = $resa->codeSite;
											$cData['typre'] = $resa->typre;
											$bredea->check_out($cData);
										}
										$bredea->closeConnect();
										$this->pms	= null;
										$this->majDatesTheoriques($idResa);
									}
									if ($genererAttestDep == 1) {
										// on génrèe l'attest dde départ : id 7
										if (in_array('FR', $lang)) {
											$lienDoc = $this->genererModeleDocument($idResa, "", 7);
										}
										if (in_array('EN', $lang)) {
											$lienDocEN = $this->genererModeleDocument($idResa, "", 7, array('lang' => 'EN'));
										}
									}
								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
									echo $ex->getMessage();
								}
							}
							##FIN BREDEA

							if ($resa->idApiSig && $resa->idReservationSig) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." idReservationSig=".$resa->idReservationSig);
								try {
									$this->initSIG($resa->idApiSig ?: 1, $resa->id);

									## Traitement en fonction du SIG
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($this->sig) {
										$this->sig->checkoutResa($resa);
									} else {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." Impossible d'initialiser le SIG");
									}
								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
									## On continue quand même normalement
								}
							}

							$msg = "Validation bien faite.";
							if ($checkoutMailType) {
								//ne pas envoyer le mail checkout si permanent meme chambre
								if (!$isPermanent) {
									$this->envoyerMail($resa->id, $checkoutMailType);
								}
							}

							$log = new Logs();
							$diff = $log->arrayDiff($resa, $this->getResaTable()->getResa($idResa));
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "Réservation : checkOut ".$resa->numeroChambre;
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "reservations";
							$log->idReservation = $idResa;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);

							// On effectue le checkout
							if ($_SESSION['USERDROIT']['mode-input-serrures'] == 'W' || $_SESSION['USERDROIT']['mode-input-serrures'] == 'R'):
								$resp = $this->encodeSerrures([], 'checkOut');
								if ($resp['success']) {
									// On récupère toutes les clés de la resa
									$clesToResas = $clesToResasTable->select(array('idResa' => (int) $resa->id))->toArray();
									foreach ($clesToResas as $key => $cleToResa) {
										// On supprime toutes les cles de la table cles, ensuite de clesToResas + clesToLogements + clesToZones
										$clesTable->delete(array('id' => (int) $cleToResa['idCles']));
										$clesToLogementTable->delete(array('idCles' => (int) $cleToResa['idCles']));
										$clesToZonesTable->delete(array('idCles' => (int) $cleToResa['idCles']));
									}
									$clesToResasTable->delete(array('idResa' => (int) $resa->id));
								}
							endif;
						}
					}
				}
			}

			if ($checkoutAuto) {
				printf("\n$nbResas réservations clôturées\n");
			}
			$view = new JsonModel(array(
				'success' => true,
				'etat' => $etatTXT,
				'idResa' => $idResa,
				'msg' => $msg,
				'confirmed' => $confirmed,
				'lienDoc' => $lienDoc,
				'lienDocEN' => $lienDocEN,
				'idGroupeResa' => $idGroupeResa,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function miseEnSommeilWL($type = "autre", $idLogement, $sommeil = 0)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");
		$logement = $this->getLogementTable()->getLogement($idLogement);
		$type = "autre";//pour ne plus traiter les co-chambre
		if ($logement) {
			if ($type == "confort") {
				$where = array('numero' => $logement->numero.'A');
				$set = array('cacher' => $sommeil);
				$this->getLogementTable()->updateLogement($set, $where);

				$where = array('numero' => $logement->numero.'B');
				$set = array('cacher' => $sommeil);
				$this->getLogementTable()->updateLogement($set, $where);
			} elseif ($type == "coChambre") {
				## on verife si l'autre confort est occupe, on rend pas dispo le confort individuel, mais juste le co-chambre checkout
				if ($sommeil == 0) {
					$codeLogSet = str_replace('A', '', $logement->numero);
					$codeLogSet = str_replace('B', '', $codeLogSet);

					$majConfort = false;
					if (strpos($logement->numero, 'A') !== false) {
						//ici le checkout est A, on cherche B si occupe
						$codeLogB = $codeLogSet.'B';
						$logementB = $this->getLogementTable()->getLogementBy(array('numero' => $codeLogB));
						if ($logementB && $logementB->cacher == 0) {
							$majConfort = true;
						}
					} elseif (strpos($logement->numero, 'B') !== false) {
						//ici le checkout est B, on cherche A si occupe
						$codeLogA = $codeLogSet.'A';
						$logementA = $this->getLogementTable()->getLogementBy(array('numero' => $codeLogA));
						if ($logementA && $logementA->cacher == 0) {
							$majConfort = true;
						}
					}

					//on maj juste le cochambre checkout
					$where = array('id' => $idLogement);
					$set = array('cacher' => $sommeil);
					$this->getLogementTable()->updateLogement($set, $where);

					if ($majConfort) {
						//on maj aussi le confort
						$where = array('numero' => $codeLogSet);
						$set = array('cacher' => $sommeil);
						$this->getLogementTable()->updateLogement($set, $where);
					}
				} else {
					$codeLogSet = str_replace('A', '', $logement->numero);
					$codeLogSet = str_replace('B', '', $codeLogSet);
					$where = array('numero' => $codeLogSet);
					$set = array('cacher' => $sommeil);
					$this->getLogementTable()->updateLogement($set, $where);
				}
			}
		}
	}



	## VALIDATION EDL AUTO
	private function validerEdlAuto($idResaOld, $idResaNew, $type = "entrant")
	{
		$tools = new Tools();
		## on cherche l edl des l ancienne resa
		$oldResa = $this->getResaTable()->getResa($idResaOld);
		$newResa = $this->getResaTable()->getResa($idResaNew);

		$locId = $oldResa->idLocataire;

		$edlOldResa = $this->getTableObjet('edl')->select(array('id_reservations' => $idResaOld, 'id_locataire' => $locId, 'id_logement' => $oldResa->idLogement))->toArray();
		if (!empty($edlOldResa) && sizeof($edlOldResa) > 0) {
			//on cree le nouveau edl
			$newEdl = $edlOldResa[0];
			$idOldEdl = $newEdl['id'];
			unset($newEdl['id']);
			$newEdl['id_reservations'] = $idResaNew;
			$newEdl['type_validation'] = 'automatique';
			$newEdl['type'] = $type;
			$newEdl['etat'] = 'terminer';
			$newEdl['date'] = date('Y-m-d H:i:s');

			$idNewEdl = $this->getEdlTable()->add($newEdl);

			if (!is_dir(getcwd()."/public/docs/locataires/".$locId)) {
				mkdir(getcwd()."/public/docs/locataires/".$locId);
			}
			if (!is_dir(getcwd()."/public/docs/locataires/".$locId."/edl-".$idNewEdl)) {
				mkdir(getcwd()."/public/docs/locataires/".$locId."/edl-".$idNewEdl);
			}
			//copie des images de l ancien vers le nouveau
			$source = getcwd()."/public/docs/locataires/".$locId."/edl-".$idOldEdl;
			$destination = getcwd()."/public/docs/locataires/".$locId."/edl-".$idNewEdl;
			$tools->copy_directory($source, $destination);

			//on recupere les cat
			$cats = $this->getEdlCatTable()->getByIdEdl($idOldEdl)->toArray();
			foreach ($cats as $keyCat => $valueCat) {
				## on cree la categorie pour le nouveau edls
				$idNewCat = $this->getEdlCatTable()->add($valueCat['nom'], $valueCat['nom_en'], $idNewEdl);
				// get all sous cats
				$sousCats = $this->getEdlSousCatTable()->getByIdEdlCat($valueCat['id'])->toArray();

				foreach ($sousCats as $keySousCat => $valueSousCat) {
					## on cree les sous cat
					$idNewSousCat = $this->getEdlSousCatTable()->add($valueSousCat['nom'], $valueSousCat['nom_en'], $idNewCat);
					// get articles
					$articlesArr = $this->getEdlArticleTable()->getByIdEdlSousCat($valueSousCat['id'])->toArray();
					//on y ajoute les 3 images si existent
					foreach ($articlesArr as $art) {
						## on ajoute les articles
						$this->getEdlArticleTable()->add(
							$art['nom'],
							$art['nom_en'],
							$art['nombre'],
							$art['etat'],
							$art['commentaire'],
							$art['type'],
							$art['cout'],
							$idNewSousCat
						);
					}
				}
			}
		}

		## on le copie sur la nouvelle resa
	}

	//si toutes les resa et le type collective sont au meme etat
	// ou au moins une resa dans le prochain etat
	private function isSameEtatLogement($logColl, $idNextEat)
	{
		if ($logColl) {
			## on verifie si tout les logement du meme batiment sont au meme etat, et le logement collective
			## on cherche les logement du batiment
			$logements = $this->getLogementTable()->getLogementsBy(array('idBatiment' => $logColl->idBatiment, 'collective' => 0));
			$logArray = array();
			foreach ($logements as $log) {
				$logArray[$log->id] = $log->numerco;
			}

			$icArr = array($logColl->idEtatIC);
			## on cherche les resa d un batiment
			$filtres = array('idBatiment' => array($logColl->idBatiment), 'idEtatResa' => array(6));
			$resas = $this->getBatimentTable()->getResasByBatiment($filtres);
			foreach ($resas as $row) {
				if (array_key_exists($row->logements_id, $logArray)) {
					$icArr[] = $row->reservations_idIntercontrat;
				} else {
					return false;
				}
			}

			if (count(array_unique($icArr)) === 1 || in_array($idNextEat, $icArr)) {
				return true;
			}
		}
		return false;
	}


	public function validermenageAction()
	{
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$dateMenage = $request->getPost('dateMenage');
			$etatTXT = null;
			$type = $request->getPost('type');//vide : validation normal, annuler: pas d intervention, valider, intervention a faire
			$commentaireIC = $request->getPost('commentaireIC');
			$commentaireIC = trim($commentaireIC);

			$nextIC = $request->getPost('nextIC');
			$interCommentaire = $request->getPost('interCommentaire');

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa dateMenage=$dateMenage type=$type nextIC=$nextIC");

			if ($nextIC) {
				$nextEtat = $this->getRealEtatintercontratTable()->getEtat($nextIC);
			}

			$ids = $request->getPost('ids');//checkout en masse
			$resaIds = array();
			$intervention = false;
			$confirmed = false;
			$confirmedAll = true;

			$msgErreurAll = "";
			$idsNextEtat = array();
			$etatSuivanteDispo = false;//on cherche si l etat suivante de l etat qu on vient de valider est dispo

			if (!empty($ids)) {
				$resaIds = $ids;
			} elseif ($idResa) {
				$resaIds[] = $idResa;
			}

			foreach ($resaIds as $idResa) {
				$msgErreur = "";
				$resa =  $this->getResaTable()->getResa($idResa);
				## on verifie si il s agit d un logement avec pieces collective
				## si oui : on verifie que tout les autre logements du meme batiment et le type collective sont au meme etat
				## si le type collective n est pas dans le meme etat, il faut le valider depuis la fiche logement du planning
				## si tous au meme etat on passe à l etat d apres


				if (!$nextEtat) {
					$nextEtat = $this->getNextEtatIC($resa->idIntercontrat);
				}

				$logColl = $this->getLogementTable()->isLogementCollective($resa->idLogement);
				if ($logColl) {
					## on verifie si tout les logement du meme batiment sont au meme etat, et le logement collective
					$isSame = $this->isSameEtatLogement($logColl, $nextEtat->id);
					if (!$isSame) {
						$msgErreur = "Veuillez vérifier que tout les autre logements du meme batiment sont au meme niveau";
					}
				}

				//verification remise_des_cle
				if ($nextEtat->default == 1) {
					//$rdc = $this->getTable('edl')->select(array('id_reservations' => $idResa))->current();
					//on verifie si on a un modele edl pour le logement
					$edlLog = $this->getTableObjet('edl_modele')->select(array('id_logement' => $resa->idLogement))->current();
					if ($resa && $resa->remise_des_cles != "coffre") {
						$msgErreur = "Vous n'avez pas encore les clès à votre disposition, le logement ne peut donc pas être réattribué";
					}
				}

				//verification logement en travaux
				$log = $this->getLogementTable()->getLogement($resa->idLogement);
				/*if($log && $log->dateDebutTravaux && $log->dateFinTravaux && strtotime(date('Y-m-d')) >= strtotime($log->dateDebutTravaux) && strtotime(date('Y-m-d')) <= strtotime($log->dateFinTravaux)){
					$msgErreur = "Logement ".$log->numero." en travaux entre ".date('d-m-Y',strtotime($log->dateDebutTravaux))." et ".date('d-m-Y',strtotime($log->dateFinTravaux));
				}*/
				if ($log) {
					$ptl = $this->getPeriodesTravaux($log->id);
					foreach ($ptl as $pt) {
						if (strtotime(date('Y-m-d')) >= strtotime($pt->dateDebutTravaux) && strtotime(date('Y-m-d')) <= strtotime($pt->dateFinTravaux)) {
							$msgErreur = "Logement ".$log->numero." en travaux entre ".date('d-m-Y', strtotime($pt->dateDebutTravaux))." et ".date('d-m-Y', strtotime($pt->dateFinTravaux));
						}
					}
				}


				## ---------------------------------------------------- ##

				if ($msgErreur == "") {
					/*
					if($nextEtat->id == 5 && $type=='annuler'){
						//si le prochain etat est disponible on le mis à null, et le logement à dispo
						$this->getLogementTable()->updateLogement(array('idEtat'=>1),array('id'=>$resa->idLogement));
						$upData = array('idIntercontrat'=>null);
						$confirmed = true;
					}elseif($nextEtat->id == 5){
						$intervention = true;
					}else{
						$this->getLogementTable()->updateLogement(array('idEtat'=>3),array('id'=>$resa->idLogement));
						$upData = array('idIntercontrat'=>$nextEtat->id);
					}
					*/

					if ($nextEtat->default == 1) {
						//si le prochain etat est disponible on le mis à null, et le logement à dispo
						// avant de mettre le logement en dispo, on verifie si il a pas déjà une autre résa

						$this->getLogementTable()->updateLogement(array('idEtat' => 1), array('id' => $resa->idLogement));
						$confirmed = true;
						$upData = array('idIntercontrat' => null);
					} else {
						$this->getLogementTable()->updateLogement(array('idEtat' => 3), array('id' => $resa->idLogement));
						$upData = array('idIntercontrat' => $nextEtat->id);
					}

					/*
					if($commentaireIC && $type == 'valider'){
						//on reste sur le meme etat
						//$upData = array('idIntercontrat'=>$nextEtat->id);
						$upData = array();
						$upData['commentaireIC'] = $commentaireIC;
						$intervention = false;
					}
					*/

					if (!empty($upData)) {
						//on ajoute dans la table intercontrat, l'etat valide avec la duree reel
						//nextEtat : c'est l etat choisi dans le popup
						$this->ajouterEtatIntercontrat($idResa, $dateMenage, $type, $interCommentaire, $nextEtat->id);


						$this->getResaTable()->updateResa($upData, array('id' => $idResa));
						$etatTXT = $nextEtat->nom;
						if ($type == 'annuler') {
							$etatTXT = "Disponible";
						}
						$confirmed = true;
						$idsNextEtat[$idResa] = $etatTXT;
					}
					$etatProchaine = $this->getNextEtatIC($nextEtat->id);
					if ($etatProchaine && $etatProchaine->default == 1) {
						$etatSuivanteDispo = true;
					}
				}
				$confirmedAll = $confirmedAll && $confirmed;
				if ($msgErreur != "") {
					$msgErreurAll .= $resa->numeroChambre."-".$msgErreur.'<br>';
				}
			}

			$view = new JsonModel(array(
				'success' => true,
				'etat' => $etatTXT,
				'idResa' => $idResa,
				'msg' => 'Validation bien faite',
				'msgErreur' => $msgErreurAll,
				'confirmed' => $confirmedAll,
				'intervention' => $intervention,
				'idsNextEtat' => $idsNextEtat,
				'etatValideEnMasse' => sizeOf($idsNextEtat),
				'etatSuivanteDispo' => $etatSuivanteDispo,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function validerdemandeAction()
	{
		$request = $this->getRequest();
		$etatTXT = "";

		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');

			$ids = $lang = $request->getPost('ids');//checkout en masse
			$resaIds = array();
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa".($ids ? " ids=".json_encode($ids) : ""));

			if (!empty($ids)) {
				$resaIds = $ids;
			} elseif ($idResa) {
				$resaIds[] = $idResa;
			}

			foreach ($resaIds as $idResa) {
				$resa =  $this->getResaTable()->getResa($idResa);
				if ($resa && $resa->etat == 10) {
					//on ajoute la demande dans bredea
					$modeEnvoiDemandePMS = $this->getCampagneTable()->getCampagneMode($resa->idCampagne)->modeEnvoiDemandePMS;
					if (!$resa->idPMS && $modeEnvoiDemandePMS == "Immediat") {
						$this->ajouterDemandeBredea($idResa);
					}
					$this->envoyerMail($idResa, 3);
					$this->getResaTable()->updateResa(array('etat' => 1), array('id' => $idResa));
				}

				$etatResa = $this->getTable('etat_reservation')->select(array('id' => 1))->current();
				$etatTXT = $etatResa->nom;
			}

			$view = new JsonModel(array(
						'success' => true,
						'etat' => $etatTXT,
						'idResa' => $idResa,
						'msg' => 'Validation bien faite',
						'confirmed' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function confirmerresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");
			$conf = $this->getConfigurationTable()->getConfig(1);

			$resa =  $this->getResaTable()->getResa($idResa);

			if ($resa && $resa->etat == 2) {
				$this->getResaTable()->updateResa(array('etat' => 3, 'dateConfirmation' => date('Y-m-d')), array('id' => $idResa));

				## Relecture de la resa pour prendre en compte les dernières modifs
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$resa =  $this->getResaTable()->getResaWithSig($idResa); ## Remonte aussi les infos de PMS
				try {
					$bredea		= null;
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## lancer le traitement sur le PMS
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$this->pms->changeEtat_affecte2confirme($resa);
						}
					}
					if ($bredea) {
						$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa));
						if ($conf->encaisAcompte != 1) {

							## on cree le soeer bredea
							$ret = $this->passerEnDossierBredea($idResa);

							## on cree la facture FDD

							if ($comptes->count() > 0) {
								$this->creerFactureFRAIS($idResa);
							}
						}
						foreach ($comptes as $c) {
							//fdd
							if ($c->solde > 0) {
								// if($ret && $c->type == 3){
								// 	$fRow = array('type'=>$c->type,'montant'=>$c->debit,'num_mvt'=>$c->num_mvt);
								// 	$this->creerFactureFDD($idResa, $fRow['type'], $fRow['montant'], "");
								// }
								//on passe les lignes compte en paye
								$dataArray = array();
								$dataArray['nature'] = "Paiement CB réussi / Successful payment";
								$dataArray['etat'] = 1;
								$dataArray['payByOgone'] = '1';
								$dataArray['solde'] = 0;
								$dataArray['dateM'] = date('Y-m-d');
								$dataArray['credit'] = $c->debit;
								$this->getTableObjet('comptes')->update($dataArray, array('id' => $c->id));
							}
						}

						//on supprimer la ligne dans la pile
						$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $idResa, 'idLocataire' => $resa->idLocataire))->current();
						if ($pile) {
							$this->getTableObjet('pile_paiement')->delete(array('id' => $pile->id));
						}
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
				}

				## Recherche d'interfaces SIG avec transfert à la confirmation des réservations
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$apiSigs	= $this->getApisigTable()->getAllActiveApiWithKey('transmitonconfirm');
				if ($apiSigs) {
					foreach ($apiSigs as $apiSig) {
						$idApiSig	= $apiSig->id;
						if ($idApiSig) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=$idApiSig");
							try {
								$this->initSIG($idApiSig, $resa->id);

								## Traitement en fonction du SIG
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($this->sig) {
									if (method_exists($this->sig, 'confirmResa')) {
										$this->sig->confirmResa($resa);
									} else {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=$idApiSig idResa=".$resa->id." pas de methode confirmResa");
									}
								} else {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=$idApiSig idResa=".$resa->id." Impossible d'initialiser le SIG");
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idApiSig=$idApiSig idResa=".$resa->id." : ERROR-exception=[".$ex->getMessage()."]");
								## On continue quand même normalement
							}
						}
					}
				}

				//envois de mail confirmation manuelle
				$this->envoyerMail($idResa, 0, 0, array('code' => 'confirmation_manuelle'));
			}

			$view = new JsonModel(array(
						'success' => true,
						'idResa' => $idResa,
						'msg' => 'Validation bien faite',
						'confirmed' => true,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function annulerrefusresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

			$resa =  $this->getResaTable()->getResa($idResa);
			if ($resa && $resa->etat == 4) {
				$this->getResaTable()->updateResa(array('etat' => 1), array('id' => $idResa));
			}

			$view = new JsonModel(array(
				'success' => true,
				'idResa' => $idResa,
				'msg' => 'Validation bien faite',
				'confirmed' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function annulerdepartresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

			$resa =  $this->getResaTable()->getResa($idResa);
			if ($resa && $resa->etat == 6) {
				$this->getResaTable()->updateResa(array('etat' => 7), array('id' => $idResa));
				try {
					## relecture des infos de PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~
					$resa =  $this->getResaTable()->getResaWithPms($idResa);
					if ($resa->idApiPms && $resa->idApiPms != ApipmsTable::ID_API_NO_PMS) {
						$this->initPMS($resa->idApiPms ?: 1, $idResa);

						## Traitement en fonction du PMS
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						if ($this->pms) {
							if (method_exists($this->pms, 'annulerCheckOut')) {
								## lancer le traitement sur le PMS
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$this->pms->annulerCheckOut($resa);
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa annulerDepartResa n'existe pas pour ".$this->pms->getClassName());
							}
						}
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
				}
			}

			$view = new JsonModel(array(
				'success' => true,
				'idResa' => $idResa,
				'msg' => 'Validation bien faite',
				'confirmed' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function toggleDossierIncompletAction()
	{
		$confirmed	= false;
		$msg		= "Modification impossible";
		$request	= $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

			try {
				$resa =  $this->getResaTable()->getResa($idResa);
				if ($resa) {
					$sousEtat	= $resa->sousEtat ? explode(',', $resa->sousEtat) : array();

					$key = array_search("dossierIncomplet", $sousEtat);
					if ($key !== false) {
						## Passer le dossier à complet
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
						unset($sousEtat[$key]);
						$title	= "Repasser le dossier à incomplet";
					} else {
						## Passer le dossier à incomplet
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$sousEtat[]	= "dossierIncomplet";
						$title		= "Passer le dossier à complet";
					}
					$newSousEtat	= implode(',', $sousEtat);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa newSousEtat=$newSousEtat");

					$this->getResaTable()->updateResa(array('sousEtat' => $newSousEtat), array('id' => $idResa));
					$confirmed	= true;
					$msg		= "Modification bien faite";
				} else {
					$msg		= "Dossier inconnu";
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
			}

			$view = new JsonModel(array(
				'success' => true,
				'confirmed' => $confirmed,
				'idResa' => $idResa,
				'msg' => $msg,
				'sousEtat' => $newSousEtat,
				'title' => $title,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function validerremboursementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$confirmed = false;

			$rmb =  $this->getTableObjet('remboursements')->select(array('idReservation' => $idResa))->current();
			if ($rmb) {
				$this->getTableObjet('remboursements')->update(array('etatDG' => 4), array('id' => $rmb->id));
				//$options = array('montantRemboursement'=>$montant,'dateRemboursement'=>$dateFact);
				$this->envoyerMail($idResa, 23);
				$confirmed = true;
			}

			$view = new JsonModel(array(
						'success' => true,
						'idResa' => $idResa,
						'msg' => 'Validation bien faite',
						'confirmed' => $confirmed,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function valideredlAction()
	{
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$valeur = $request->getPost('valeur');

			$resa =  $this->getResaTable()->getResa($idResa);

			if ($resa) {
				$this->getResaTable()->updateResa(array('EtatDesLieux' => $valeur), array('id' => $idResa));
			}

			$texte = ($valeur == '1') ? 'Retour EDL OK' : 'Non Retour';

			$view = new JsonModel(array(
						'success' => true,
						'texte' => $texte,
						'idResa' => $idResa,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}



	public function updateStatutAssuranceAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$statutAssur = (int) $request->getPost('statut');
			$selected = $selected1 = $selected2 = "";
			$statut = ("Non traitée");
			if ($statutAssur == 1) {
				$statut = ("Refusée");
				$selected1 = "selected='selected'";
				$selected = $selected2 = "";
			} elseif ($statutAssur == 2) {
				$statut = ("Validée");
				$selected2 = "selected='selected'";
				$selected = $selected1 = "";
			} else {
				$selected = "selected='selected'";
				$selected1 = $selected2 = "";
			}


			$options = "<option value='' $selected>".("Non traitée")."</option>";
			$options .= "<option value='1' $selected1>".("Refusée")."</option>";
			$options .= "<option value='2' $selected2>".("Validée")."</option>";


			$this->getResaTable()->updateResa(array('statutAssur' => $statutAssur), array('id' => $idResa));

			$view = new JsonModel(array(
						'success' => true,
						'statut' => $statut,
						'idStatut' => $statutAssur,
						'options' => $options,
						'idResa' => $idResa,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function uploaddocsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			//print_r($_FILES);
			$idLoc = $request->getPost('idLocataire');
			//echo "loc : ".$idLoc;
			if (!is_dir(getcwd()."/public/docs/locataires/".$idLoc)) {
				mkdir(getcwd()."/public/docs/locataires/".$idLoc);
			}

			$folder = "./public/docs/locataires/".$idLoc;
			$dossier = "docs/locataires/".$idLoc;
			$passer = 0;//0:pas fourni , 1:pas chargé, 2:extension non valide, 3:uploader
			$namePJ = "";

			$filedName = "";
			$champId = "";
			if (isset($_FILES['attestationBourse'])) {
				$filedName = "attestationBourse";
			} elseif (isset($_FILES['certificatMedical'])) {
				$filedName = "certificatMedical";
			} elseif (isset($_FILES['certificatAssur'])) {
				$filedName = "certificatAssur";
			} else {
				##le document dynamique
				$session = new Container('extra');
				$docsFields = $session->docsFields;
				foreach ($docsFields as $row) {
					if (isset($_FILES[$row->equivalentSql])) {
						$filedName = $row->equivalentSql;
						$champId = $row->equivalentSql;
						break;
					}
				}
			}

			if (isset($_FILES[$filedName]) && $_FILES[$filedName]['error'] == 0) {
				$passer = 1;

				$extension = pathinfo($_FILES[$filedName]['name'], PATHINFO_EXTENSION);
				$filename = pathinfo($_FILES[$filedName]['name'], PATHINFO_FILENAME);

				$nameDoc = "pj_".$this->removeAccent($filename)."_".date('Y-m-d-his').".".$extension;
				$nameDoc = date('Ymd')."_".$filedName."_".$idLoc.".".$extension;
				$notallowed = array('exe');

				if (in_array(strtolower($extension), $notallowed)) {
					$passer = 2;
				} else {

					//unlink($folder.'/'.$conf->logo);

					if (move_uploaded_file($_FILES[$filedName]['tmp_name'], $folder.'/'.$nameDoc)) {
						//upload réussi

						$passer = 3;
					}
				}
			}


			$msg = "";
			switch ($passer) {
				case 0: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 1: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 2: $msg = "<span class='error red'>Erreur extension(seulement pdf autorisé)</span>";
					break;
				case 3: $msg = "<span class='success green'>Fichier uploader : <a class='doc-link pj-link' href='#' target='_blank'>$nameDoc </a></span>";
					break;
			}


			$view = new JsonModel(array(
						'success' => true,
						'passer' => $passer,
						'msg' => utf8_encode($msg),
						'docname' => $nameDoc,
						'idLoc' => $idLoc,
						'pjname' => $nameDoc,
						'dossier' => $dossier,
						'champ' => $champId,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadModeAR()
	{
		$resultSet = $this->getLocatairesAccesResaTable()->fetchAll();
		$rows = array();
		foreach ($resultSet as $row) {
			$rows[] = $row;
		}

		$acces = array('1' => 'Oui', '0' => 'Non', '2' => utf8_encode('Accès à la campagne fermée'));

		$progs = $this->getProgrammeTable()->getProgrammesParent();
		$progList = array();
		foreach ($progs as $p) {
			$progList[$p->id] = $p->nom;
		}
		asort($progList);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/modeaccesresa')
				->setVariables(array(
					'rows' => $rows,
					'acces' => $acces,
					'progs' => $progList,
					'config' => $this->getConfigurationTable()->getConfig(1),
				));

		$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);
		return $htmlOutput;
	}

	public function loadmodeaccesresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$htmlOutput = $this->loadModeAR();

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadmodefactureAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modefacture')
			->setVariables(array(
					'trigger' => false,
					'modeConsolide' => 0,
					'champModalHtml' => $this->loadChampsModal('facture'),
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
					 'success' => true,
					  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadmodeprestationAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modeprestation')
			->setVariables(array(
					'trigger' => false,
					'modeConsolide' => 0,
					'champModalHtml' => $this->loadChampsModal('prestation'),
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadlistefacturesAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$trigger = $request->getPost('trigger') ? true : false;
			$modeConsolide = $request->getPost('modeConsolide', 0);
			$mode = $request->getPost('mode', '');
			$typeFact = $request->getPost('typeFact');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');

			if ($mode == 'debiteurs') {
				$htmlOutput = $this->loadListeFactures($trigger, $modeConsolide);
			} else {
				if (!$dateDebut) {
					$dateDebut = date('Y').date('m').'01';
				}
				if (!$dateFin) {
					$now = date('Y-m-d');
					if ($dateDebut) {
						$now = $dateDebut;
					}

					$dateFin = date("Y-m-t", strtotime($now));
				}


				$cData = array('dateDebut' => $dateDebut, 'dateFin' => $dateFin, 'typeFact' => $typeFact, 'mode' => $mode);

				if ($mode == "remboursement") {
					//$htmlOutput = $this->loadRemboursements($cData);
				} elseif ($mode == "prelevement") {
					//$htmlOutput = $this->loadPrelevementListe($cData);
				} else {
					//$htmlOutput = $this->loadFacturesMensuelles($cData);
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadListeFactures($trigger = false, $modeConsolide = 0)
	{
		$rows = array();

		if ($trigger) {
			$factures = $this->lireToutesLesFacturesBredea();

			$tablesSql = array('locataires' => 'nomLocataire');
			$where = array();
			$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
			$where[] = array('table' => 'reservations', 'champ' => 'numDossier', 'valeur' => 'NOTNULL');
			$where[] = array('table' => 'reservations', 'champ' => 'codeSite', 'valeur' => 'NOTNULL');

			$rowsResa = $this->getResaTable()->getListe(null, "FR", array('tables' => $tablesSql, 'where' => $where));


			foreach ($rowsResa as $resa) {
				$key = $resa->codeSite.'_'.$resa->numDossier;
				if (!empty($factures[$key])) {
					$fact = $factures[$key];
					$row = array();
					$row['idLocataire'] = $resa->idLocataire;
					$row['nomLocataire'] = $resa->nomLocataire;
					$row['prenomLocataire'] = $resa->prenomLocataire;
					$row['dateArrivee'] = $resa->dateArrivee;
					$row['dateDepart'] = ($resa->dateDepart && $resa->dateDepart != '0000-00-00' && $resa->dateDepart != '1970-01-01') ? $resa->dateDepart : null;
					$row['numeroChambre'] = $resa->numeroChambre;
					$row['debit'] = $fact['debit'];
					$row['credit'] = $fact['credit'];
					$row['solde'] = $fact['solde'];
					$row['idReservation'] = $resa->idReservation;
					$row['email1Locataire'] = $resa->emailLocataire;
					$row['email2Locataire'] = $resa->emailHec;
					if ($modeConsolide == 1) {
						// une ligne par locataire
						$row['dateArrivee'] = "";
						$row['dateDepart'] = "";
						$row['numeroChambre'] = "";
						$rows[$resa->idLocataire] = $row;
						if (!empty($rows[$resa->idLocataire]['solde'])) {
							$row['solde'] += $fact['solde'];
						} else {
							$row['solde'] = $fact['solde'];
						}
					} else {
						$rows[$key] = $row;
					}
				}
			}
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/modefacturetable')
		->setVariables(array(
				"rows" => $rows,
				"trigger" => $trigger,
				"modeConsolide" => $modeConsolide,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);
		return $htmlOutput;
	}

	### fonction qui lit toutes les factures, mode debiteurs
	public function lireToutesLesFacturesBredea($idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$return =  array();
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					$return = $bredea->lireToutesLesFactures();
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}

		return $return;
	}

	################################################################################
	##                          mode Intercontrat                                 ##
	################################################################################

	public function loadmodeintercontratAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {

			// Lecture des descriptions des champs des logements
			$jsonICDatatableState = $request->getPost('jsonICDatatableState', array());
			$jsonDatatableFrom  = 'POST';
			if (empty($jsonICDatatableState)) {
				$jsonICDatatableState = $this->loadIntercontratState();
				$jsonDatatableFrom  = 'BDD';
			}

			$jsonICDatatableFilter = array_key_exists('filter', $jsonICDatatableState) ? $jsonICDatatableState['filter'] : [];

			// Valeurs uniques pour les différents selects
			$selectOptions	= array();

			// Constitution d'une liste des lignes
			$rowsAll = $listeChampsAffiches = array();

			if ($jsonICDatatableFilter) {
				// Initialisation de la liste des champs de logements
				$formFields     = $this->getIntercontratFields($jsonICDatatableFilter);

				// Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				$listeChampsAffiches    = $this->getlisteChampsAffichesIC($jsonICDatatableFilter, $formFields);
				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$rowsAll = $this->getTableIntercontratServerSide()->getIntercontratWithAllFields($adapter, $listeChampsAffiches);

				// Constitution de la liste des options
				if ($rowsAll) {
					foreach ($rowsAll as $_key => $_row) {
						foreach ($_row as $_colName => $_value) {
							if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
								}
								$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
								if (!$_options || !in_array($_value, $_options)) {
									$selectOptions[$_colName][] = $_value;
								}
							}
						}
					}
				}

				// Tri de ces options dans l'ordre alphabétique
				foreach ($selectOptions as $_colName => $_options) {
					sort($selectOptions[$_colName], SORT_STRING);
				}
			}

			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/modeintercontrat')
				->setVariables(array(
					'rows' 		=> array(),
					'ICFields' 	=> isset($formFields) ? $formFields['ICFields'] : [],
					'logeFields' 	=> isset($formFields) ? $formFields['logeFields'] : [],
					'batiFields' 	=> isset($formFields) ? $formFields['batiFields'] : [],
					'resiFields' 	=> isset($formFields) ? $formFields['resiFields'] : [],
					'i'				=> 1,
					'jsonICDatatableState' => $jsonICDatatableState,
					'selectOptions'	=> $selectOptions,
					'config' => $this->getConfigurationTable()->getConfig(1),
				));

			$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'champs' => $listeChampsAffiches,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadIntercontratState()
	{
		$stateArr	= array();
		$stateObj	= $this->getTableObjet('intercontrat_state')->select()->current();
		if ($stateObj) {
			$state	= json_decode($stateObj->data, 1);
			if ($state && array_key_exists('filter', $state)) {
				$stateArr	= $state;
			}
		}
		return	$stateArr;
	}

	public function savestateintercontratAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonICDatatableState = $request->getPost('jsonICDatatableState', array());

			$ICStateObj	= $this->getTableObjet('intercontrat_state')->select()->current();
			if ($ICStateObj) {
				$this->getTableObjet('intercontrat_state')->update(array('data' => json_encode($jsonICDatatableState)));
			} else {
				$this->getTableObjet('intercontrat_state')->insert(array('data' => json_encode($jsonICDatatableState)));
			}
			$view = new JsonModel(['success' => true]);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function getIntercontratFields($jsonDatatableFilter = array())
	{
		$logeFields = $batiFields = $resiFields = $ICFields = array();
		$activeFields = ['ICRow' => []];

		$tableObj = new Tables('champs_interccontrat', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select1 = $tableObj->getTable()->getSql()->select();
		$select1->where('idTheme IN (1,2,3,4)');
		$select1->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select1);

		if ($themeResult) {
			foreach ($themeResult as $row) {
				if ($row->idTheme == 2) {
					$fieldType = 'batiRow';
				} elseif ($row->idTheme == 3) {
					$fieldType = 'resiRow';
				} elseif ($row->idTheme == 4) {
					$fieldType = 'logeRow';
				} else {
					$fieldType = 'ICRow';
				}

				if ($jsonDatatableFilter) {
					$activeFields[$fieldType][$row->code] = $row;
					$row->checked = array_key_exists($row->code, $jsonDatatableFilter);
				}

				if ($row->idTheme == 2) {
					$batiFields[$row->code] = $row;
				} elseif ($row->idTheme == 3) {
					$resiFields[$row->code] = $row;
				} elseif ($row->idTheme == 4) {
					$logeFields[$row->code] = $row;
				} else {
					$ICFields[$row->code] = $row;
				}
			}
		}

		return array(
			'ICFields' 	=> $ICFields,
			'logeFields' 	=> $logeFields,
			'batiFields' 	=> $batiFields,
			'resiFields' 	=> $resiFields,
			'activeFields'	=> $activeFields,
		);
	}

	private function getlisteChampsAffichesIC($jsonDatatableFilter, $formFields)
	{
		## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$listeChampsAffiches	= array(
			'intercontrat_id' => array('dyn' => 0, 'typeField' => 'ICFields', 'idTypeHtml' => 5, 'table' => 'intercontrat', 'equivalentSql' => 'id', 'visible' => true),
		);

		if ($jsonDatatableFilter && $formFields) {
			foreach ($jsonDatatableFilter as $fieldName => $field) {
				if ($fieldName && !array_key_exists($fieldName, $listeChampsAffiches)) {
					## Recherche du champ dans les différentes listes de champs
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					foreach ($formFields as $_typeField => $_fields) {
						if ($_typeField == "activeFields") {
							continue;
						}
						$_field = array_key_exists($fieldName, $_fields) ? $_fields[$fieldName] : null;
						if ($_field) {
							if ($_typeField == 'dynFields') {
								$listeChampsAffiches[$fieldName] = array(	'dyn' => 1,
														'typeField' => $_typeField,
														'idTypeHtml' => $_field->idTypeHtml,
														'table' => $_field->table,
														'idChamp' => $_field->idChamp,
														'equivalentSql' => $_field->equivalentSql,
														'sourceListe' => $_field->sourceListe,
														'visible' => true);
							} else {
								$listeChampsAffiches[$fieldName] = array(	'dyn' => 0,
														'typeField' => $_typeField,
														'idTypeHtml' => $_field->idTypeHtml,
														'table' => $_field->table,
														'idChamp' => $_field->id,
														'equivalentSql' => $_field->equivalentSql,
														'sourceListe' => $_field->sourceListe,
														'visible' => true);
							}
							break;
						}
					}
				}
			}
		}
		return $listeChampsAffiches;
	}

	public function getServerJsonDataICAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('data' => [], 'draw' => 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);
			/*$view = new JsonModel($output);
			$view->setTerminal(true);
			return($view);*/

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonICDatatableState		= $this->loadIntercontratState();
			$jsonICDatatableFilter	= $jsonICDatatableState ? $jsonICDatatableState['filter'] : [];

			if ($jsonICDatatableFilter && $columns) {
				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getIntercontratFields($jsonICDatatableFilter);

				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$listeChampsAffiches	= array(
					'intercontrat_id' => array('dyn' => 0, 'typeField' => 'ICFields', 'idTypeHtml' => 5, 'table' => 'intercontrat', 'equivalentSql' => 'id', 'visible' => true),
				);

				foreach ($columns as $_key => $_column) {
					$_colName	= $_column['data'];
					if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
						## Recherche du champ dans les différentes listes de champs
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($formFields as $_typeField => $_fields) {
							if ($_typeField == "activeFields") {
								continue;
							}
							$_field = array_key_exists($_colName, $_fields) ? $_fields[$_colName] : null;
							if ($_field) {
								if ($_typeField == 'dynFields') {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->idChamp,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								} else {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->id,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								}
								break;
							}
						}
					}
				}

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where	= "";
				$rowsAll = $this->getTableIntercontratServerSide()->getIntercontratWithAllFields($adapter, $listeChampsAffiches, $where);
				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);

				if ($rowsAll) {
					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5 || $_col[idTypeHtml] == 12 || $_col[idTypeHtml] == 13) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					if ($colDates) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							foreach ($colDates as $_colName) {
								$rowValue	= $row[$_colName];
								if ($rowValue && strpos($rowValue, '-') == 2) {
									## Date au format dd-mm-yyyy -> il faut convertir
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									list($dd, $mm, $yyyy)	= explode("-", $rowValue);
									$row[$_colName]		= "$yyyy-$mm-$dd";
								}
							}
							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}

					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonICDatatableFilter as $fieldName => $field) {
						$searchTypes[$fieldName]	= $field['type'];
						if (in_array($fieldName, $colRadios)) {
							$searchTypes[$fieldName]	= "text";
						}//traiter les champs radio comme des text
						if (in_array($fieldName, $colCheckbox)) {
							$searchTypes[$fieldName]	= "checkbox";
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));

					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column['name'];
						$value		= $column['search']['value'];
						if ($colName && $column['searchable'] && $value) {
							$searchType	= $searchTypes[$colName];
							if ($searchType == 'date' || $searchType == 'number') {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max)		= explode("|", $value);
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['min']		= $min;
								$searchs[$colName]['max']		= $max;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['text']	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search[min] && $rowValue < $search[min]) {
										continue 2;
									}
									if ($search[max] && $rowValue > $search[max]) {
										continue 2;
									}
								} elseif ($search['type'] == 'number') {
									if ($search['vide'] == '1') {
										$condVide = (trim($row[$search['colInd']]) != '');
										if ($search[min] != '') {
											if ($condVide && $rowValue < $search[min]) {
												continue 2;
											}
											if ($search[max] != '') {
												if ($condVide && $rowValue > $search[max]) {
													continue 2;
												}
											}
										} else {
											if ($search[max] != '') {
												if ($condVide && $rowValue > $search[max]) {
													continue 2;
												}
											} else {
												if ($condVide) {
													continue 2;
												}
											}
										}
									} else {
										if ($search[min] != ''  && $rowValue < $search[min]) {
											continue 2;
										}
										if ($search[max] != '' && $rowValue > $search[max]) {
											continue 2;
										}
									}

								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}

					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					uasort($rowsSel, function ($a, $b) use ($sortOrder) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
								//mettre les dates vide à la fin
								if (!$a[$_colName]) {
									return 1;
								} else {
									return -1;
								}
							} else {
								return strcasecmp($a[$_colName], $b[$_colName]);
							}
						} else {
							return strcasecmp($b[$_colName], $a[$_colName]);
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}

				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
			}

			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;

			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}



	################################################################################
	##                         FIN mode Intercontrat                              ##
	################################################################################

	## type factues affectation
	/*public function loadfacturesaffectationAction(){
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()){

			$typeFact = $request->getPost('typeFact');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');

			$cData = array('dateDebut'=>$dateDebut,'dateFin'=>$dateFin,'typeFact'=>$typeFact);

			$htmlOutput = $this->loadFacturesMensuelles($cData);

			$view = new JsonModel(array(
						'success'=>true,
						  'htmlOP'=>$htmlOutput,

			));

			$view->setTerminal(true);
			return($view);
		}
		exit();
	}*/

	public function facturationAction()
	{
		return $this->redirect()->toRoute('zfcadmin/brouillard');
	}

	public function brouillardAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$msg = "";

		$moisFR = array('01' => "Janvier",
						'02' => "Février",
						'03' => "Mars",
						'04' => "Avril",
						'05' => "Mai",
						'06' => "Juin",
						'07' => "Juillet",
						'08' => "Août",
						'09' => "Septembre",
						'10' => "Octobre",
						'11' => "Novembre",
						'12' => "Décembre");

		$now = date('Y-m-d');
		$mois = array();
		$lastMonth = date('m', strtotime($now." - 1 month"));
		$yearOfLastMonth = date('Y', strtotime($now." -1 month"));

		$mois[$lastMonth.'-'.$yearOfLastMonth] = $moisFR[$lastMonth]." ".$yearOfLastMonth;//mois courant
		for ($i = 0;$i <= 1;$i++) {
			$moisNum = date('m', strtotime($now." + $i month"));
			$year = date('Y', strtotime($now." + $i month"));
			$mois[$moisNum.'-'.$year] = $moisFR[$moisNum]." ".$year;
		}

		//liste des residences
		$residencesRows = $this->getResidencesTable()->fetchAll();
		$residences = array();
		foreach ($residencesRows as $rd) {
			$residences[$rd->id] = $rd->nom;
		}

		$request = $this->getRequest();
		if ($request->isPost()) {
			$moisAnnee = $request->getPost('moisValide');
			$idResidence = (int)$request->getPost('idResidence');
			$libre = $request->getPost('libre');
			$dejavalide = $this->getTableObjet('brouillard')->select(array('mois' => $moisAnnee, 'idResidence' => $idResidence))->current();
			//if(!$dejavalide){
			$data = array();
			$data['dateValidation'] = date('Y-m-d H:i:s');
			$data['mois'] = $moisAnnee;
			$data['etat'] = 'valide';
			$data['libre'] = $libre;
			$data['idGestionnaire'] = $gestId;
			$data['idResidence'] = $idResidence;
			$this->getTableObjet('brouillard')->insert($data);
			$moisVar = substr($moisAnnee, 0, 2);
			$msg = "Mois ".$moisFR[$moisVar].' bien validé';

			//return $this->redirect()->toRoute('zfcadmin/brouillard');
			/*}else{
				$moisVar = substr($moisAnnee,0,2);
				$msg = "Mois ".$moisFR[$moisVar].' déjà validé pour la résidence '.$residences[$idResidence];
			}*/
		}


		//on enleve les mois valide
		$moisValideRes = $this->getTableObjet('brouillard')->select(array('etat' => 'valide'));
		$moisValide = array();
		$gestionnaires = array();
		foreach ($moisValideRes as $mv) {
			//unset($mois[$mv->mois]);
			$moisValide[] = $mv;
			$gest = $this->getTableObjet('user')->select(array('user_id' => $mv->idGestionnaire))->current();
			$gestionnaires[$mv->idGestionnaire] = $gest->display_name;
		}



		return array(
			'mois' => $mois,
			'moisValide' => $moisValide,
			'moisFR' => $moisFR,
			'gestionnaires' => $gestionnaires,
			'residences' => $residences,
			'msg' => $msg,
			);
	}


	## type lecture factures mensuelles

	/*public function loadfacturesmoisAction(){
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()){

			$typeFact = $request->getPost('typeFact');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			$mode = $request->getPost('mode');

			if(!$dateDebut){
				$dateDebut = date('Y').date('m').'01';
			}
			if(!$dateFin){
				$now = date('Y-m-d');
				if($dateDebut){
					$now = $dateDebut;
				}

				$dateFin = date("Y-m-t", strtotime($now));
			}


			$cData = array('dateDebut'=>$dateDebut,'dateFin'=>$dateFin,'typeFact'=>$typeFact,'mode'=>$mode);

			if($mode == "remboursement"){
				$htmlOutput = $this->loadRemboursements($cData);
			}elseif($mode == "prelevement"){
				$htmlOutput = $this->loadPrelevementListe($cData);
			}else{
				$htmlOutput = $this->loadFacturesMensuelles($cData);
			}


			$view = new JsonModel(array(
						'success'=>true,
						  'htmlOP'=>$htmlOutput,

			));

			$view->setTerminal(true);
			return($view);
		}
	}*/

	private function getTotalFraisParResa()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$totalFraisParResa = array();
		$table = $this->getTableObjet('comptes');
		$select = $table->getSql()->select();
		$select->columns(array(
			'idReservation',
			'total' => new \Zend\Db\Sql\Expression('SUM(comptes.solde)'),
		));
		$select->join('reservations', 'reservations.id =comptes.idReservation', array('idResa' => 'id'));
		$select->where("comptes.solde > 0 AND reservations.etat = 2 AND reservations.archive='0'");
		$select->group('comptes.idReservation');
		$resultSet = $table->selectWith($select);
		foreach ($resultSet as $row) {
			$totalFraisParResa[$row->idReservation] = $row->total;
		}
		return $totalFraisParResa;
	}


	private function loadFacturesMensuelles($cData)
	{

		/*
		B00… Résident - Date affectation - N° logement - Résidence- Etat réservation
		*/

		$conf = $this->getConfigurationTable()->getConfig(1);

		$mode = !empty($cData['mode']) ? $cData['mode'] : '';//

		$factures = $this->lireFacturesDuMoisBredea($cData);

		$tablesSql = array('locataires' => 'nomLocataire', 'etat_reservation' => 'etatReservation', 'pile_paiement' => 'statutPaiement');
		$where = array();
		$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
		if ($mode == "affectation") {
			$where[] = array('table' => 'reservations', 'champ' => 'numResa', 'valeur' => 'NOTNULL');
		} else {
			$where[] = array('table' => 'reservations', 'champ' => 'numDossier', 'valeur' => 'NOTNULL');
		}

		$where[] = array('table' => 'reservations', 'champ' => 'codeSite', 'valeur' => 'NOTNULL');

		//$where[] = array('table'=>'reservations','champ'=>'dateOption','valeur'=>'','min'=>date('Y-m-d',strtotime($cData['dateDebut'])));
		//$where[] = array('table'=>'reservations','champ'=>'dateOption','valeur'=>'','min'=>date('Y-m-d',strtotime($cData['dateFin'])));

		$totalFraisParResa = array();
		if ($mode == "affectation") {
			//on fait le total des frais initiaux comme total de la facture
			$totalFraisParResa = $this->getTotalFraisParResa();
		}

		$rowsResa = $this->getResaTable()->getListe(null, "FR", array('tables' => $tablesSql, 'where' => $where));
		$rows = array();
		foreach ($rowsResa as $resa) {
			$key = $resa->codeSite.'_'.$resa->numDossier;
			$cond = true;
			if ($mode == "affectation") {
				$cond = strtotime($resa->dateOption) >= strtotime($cData['dateDebut']) && strtotime($resa->dateOption) <= strtotime($cData['dateFin']);
				if (!$resa->numDossier) {
					$key = $resa->codeSite.'_'.$resa->numResa;
				}
			}

			if (!empty($factures[$key]) && $cond) {
				$factRows = $factures[$key];
				foreach ($factRows as $fact) {
					//$fact = $factures[$key];
					$row = array();
					$row['nomLocataire'] = $resa->nomLocataire;
					$row['prenomLocataire'] = $resa->prenomLocataire;
					$row['dateFacture'] = $fact['jvt_dtfac'];
					$row['numeroFacture'] = $fact['jvt_nofac'];
					$row['montantFacture'] = $fact['jvt_presteuro'];
					$row['idReservation'] = $resa->idReservation;

					$row['codeLocataire'] = $resa->codeLocataire;
					$row['etatReservation'] = $resa->etatReservation;
					$row['numeroChambre'] = $resa->numeroChambre;
					$row['residence'] = $resa->residence;
					$row['dateOption'] = $resa->dateOption;
					$row['statutPaiement'] = $resa->statutPaiement;
					$row['msgErreur'] = $resa->msgErreur;
					$row['methodePaiement'] = $resa->methodePaiement;
					$row['paiementComment'] = $resa->paiementComment;

					$row['dateArrivee'] = $resa->dateArrivee;
					$row['dateDepart'] = ($resa->dateDepart && $resa->dateDepart != '0000-00-00' && $resa->dateDepart != '1970-01-01') ? $resa->dateDepart : null;

					$row['datePaiement'] = "";
					$row['montantPaiement'] = 0;
					$row['modePaiement'] = "";
					$reglements = $fact['reglements'];
					$ok = false;
					foreach ($reglements as $reg) {
						$row['datePaiement'] = $reg['reg_date'];
						$row['montantPaiement'] += $reg['reg_mteuro'];
						$row['modePaiement'] = $reg['reg_modreg'];
						$row['statutPaiement'] = 'ok';

						if (!$ok && $mode == "affectation" && $fact['jvt_presteuro'] < $fact['encais_mteuro'] && $fact['encais_nopiece'] == $reg['reg_nopiece']) {
							$ok = true;
							$row['montantPaiement'] = $fact['encais_mteuro'];
						}
					}


					$row['solde'] = $fact['solde'];
					$rows[] = $row;
				}
			} elseif ($mode == "affectation" && ($resa->etat == 2 || $resa->etat == 3)
			&& strtotime($resa->dateOption) >= strtotime($cData['dateDebut']) && strtotime($resa->dateOption) <= strtotime($cData['dateFin'])) {
				$row = array();
				$row['nomLocataire'] = $resa->nomLocataire;
				$row['prenomLocataire'] = $resa->prenomLocataire;
				$row['dateFacture'] = "";
				$row['numeroFacture'] = "";
				$row['montantFacture'] = !empty($totalFraisParResa[$resa->id]) ? $totalFraisParResa[$resa->id] : "";
				$row['idReservation'] = $resa->idReservation;

				$row['codeLocataire'] = $resa->codeLocataire;
				$row['etatReservation'] = $resa->etatReservation;
				$row['numeroChambre'] = $resa->numeroChambre;
				$row['residence'] = $resa->residence;
				$row['dateOption'] = $resa->dateOption;
				$row['statutPaiement'] = $resa->statutPaiement;
				$row['msgErreur'] = $resa->msgErreur;
				$row['methodePaiement'] = $resa->methodePaiement;
				$row['paiementComment'] = $resa->paiementComment;

				$row['datePaiement'] = "";
				$row['montantPaiement'] = 0;
				$row['modePaiement'] = "";
				$rows[$key] = $row;
			}
		}



		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/facturesmois')
		->setVariables(array(
				"rows" => $rows,
				"delaiPaiement" => $conf->delaiPaiement,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);
		return $htmlOutput;
	}

	### foncion qui charge les remboursement
	public function loadRemboursements($cData = array(), $idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$return =  array();
		$rows = array();
		$idsResa = array();
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					##return un array : avec deux cle : 'todo'=> remboursement a faire et 'done'=>remboursement faire,
					##et chamqu'un avec cle site_numDossier
					$return = $bredea->lireListeRemboursement($cData);
					//print_r($return);exit();
					if (!empty($return)) {
						$todo = $return['todo'];//remboursement a faire

						$done = $return['done'];// remboursement faite
						if (!empty($todo) || !empty($done)) {
							$tablesSql = array('locataires' => 'nomLocataire', 'etat_reservation' => 'etatReservation', 'remboursements' => 'etatRemboursement');
							$where = array();
							$where[] = array('table' => 'reservations', 'champ' => 'archive', 'valeur' => '0');
							$where[] = array('table' => 'reservations', 'champ' => 'numDossier', 'valeur' => 'NOTNULL');
							$where[] = array('table' => 'reservations', 'champ' => 'codeSite', 'valeur' => 'NOTNULL');

							$rowsResa = $this->getResaTable()->getListe(null, "FR", array('tables' => $tablesSql, 'where' => $where));

							foreach ($rowsResa as $resa) {
								$key = $resa->codeSite.'_'.$resa->numDossier;

								$row = array();
								$row['soldeCompte'] = "";
								if (!empty($todo[$key])) {
									$dg = $todo[$key];
									$row['montantFacture'] = $dg['montant'];
									$row['numeroFacture'] = $dg['noPiece'];
									$row['soldeCompte'] = $dg['soldeCompte'];
								}
								if (!empty($done[$key])) {
									$rmb = $done[$key];
									$row['datePaiement'] = $rmb['dateFact'];
									$row['numeroFacture'] = $rmb['noPiece'];
								}
								$row['remarque'] = "";
								if (empty($todo[$key]) && empty($done[$key])) {
									//continue;
									//on cherche si il a une nouvelle resa en etat 1
									$newResa = $this->getResaTable()->getResaBy(array('idLocataire' => $resa->idLocataire, 'etat' => 1, 'archive' => '0'))->current();
									if ($newResa && $newResa->id != $resa->id) {
										$txt = "";
										if ($newResa->etat == 1) {
											$txt = "(Nouvelle réservation en demande validée)";
										}
										if ($newResa->etat == 9) {
											$txt = "(Nouvelle réservation en pré-affectation)";
										}
										$row['remarque'] = "Transfert de DG impossible $txt";
										$row['etatDG'] = 6;
									} else {
										continue;
									}
								}

								$row['nomLocataire'] = $resa->nomLocataire;
								$row['prenomLocataire'] = $resa->prenomLocataire;
								$row['dateFacture'] = "";
								$row['idReservation'] = $resa->idReservation;

								$row['codeLocataire'] = $resa->codeLocataire;
								$row['etatReservation'] = $resa->etatReservation;
								$row['numeroChambre'] = $resa->numeroChambre;
								$row['residence'] = $resa->residence;

								$row['etatDG'] = $resa->etatDG;
								$row['rib'] = $resa->rib;
								$row['nomRIB'] = $resa->nomRIB;
								$row['bic'] = $resa->bic;

								//on cherche si il a une nouvelle resa en etat 1
								$newResaRows = $this->getResaTable()->getResaBy(array('idLocataire' => $resa->idLocataire, 'archive' => '0'));
								foreach ($newResaRows as $newResa) {
									if ($newResa->id != $resa->id && ($newResa->etat == 1 || $newResa->etat == 9)) {
										$txt = "";
										if ($newResa->etat == 1) {
											$txt = "(Nouvelle réservation en demande validée)";
										}
										if ($newResa->etat == 9) {
											$txt = "(Nouvelle réservation en pré-affectation)";
										}
										$row['remarque'] = "Transfert de DG impossible $txt";
										$row['etatDG'] = 6;
									}
								}


								$rows[] = $row;
								$idsResa[] = $row['idReservation'];
							}
						}
					}

					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}

		//on cherche les partie avec nouvelle resa en etat 1 ou 9

		$tableResa = $this->getTableObjet('reservations');
		$select = $tableResa->getSql()->select();
		$select->join('locataires', 'reservations.idLocataire = locataires.id', array('idLocataire' => 'id',
																					'nomLocataire' => 'nom',
																					'prenomLocataire' => 'prenom',
																					'codeLocataire',
																					), 'LEFT');
		$select->join('etat_reservation', 'reservations.etat = etat_reservation.id', array('idEtat' => 'id', 'etatReservation' => 'nom'), 'LEFT');

		$select->join('logements', 'logements.id = reservations.idLogement', array('idLogement' => 'id'), 'LEFT');
		$select->join('batiments', 'batiments.id = logements.idBatiment', array('batiment' => 'nom', 'idBatiment' => 'id'), 'LEFT');
		$select->join('residences', 'residences.id = batiments.idResidence', array('residence' => 'nom', 'idResidence' => 'id'), 'LEFT');

		$select->where(array('reservations.etat' => 6, 'reservations.archive' => '0'));
		$resasParti = $tableResa->selectWith($select);

		foreach ($resasParti as $resa) {
			if (!in_array($rp->id, $idsResa)) {
				if ($resa->idNouvelleResa || !$resa->numDossier || !$resa->codeSite) {
					//on compte pas les changement de logement, ou lignes sans numDossier
					continue;
				}

				$continue = true;
				$edl = $this->getTableObjet('edl')->select(array('type' => 'sortie', 'id_reservations' => $resa->id))->current();
				if ($edl) {
					if (!$edl->num_facture ||  $edl->num_facture == "") {
						//on cherche si il ya des prestation associe, on lance pas le DG
						// on le lance si pas de prestation ou si l etat de prestation = facture
						$prestationsEdl = $this->getTableObjet('edl_prestations')->select(array('edl_id' => $edl));
						if ($prestationsEdl->count() > 0) {
							$continue = false;
						}
					}
				}

				$newResaRows = $this->getResaTable()->getResaBy(array('idLocataire' => $resa->idLocataire, 'archive' => '0'));
				foreach ($newResaRows as $newResa) {
					if ($newResa->id != $resa->id && ($newResa->etat == 1 || $newResa->etat == 9)) {
						$row = array();
						$row['soldeCompte'] = "";
						$txt = "";
						if ($newResa->etat == 1) {
							$txt = "(Nouvelle réservation en demande validée";
						}
						if ($newResa->etat == 9) {
							$txt = "(Nouvelle réservation en pré-affectation";
						}
						if ($continue) {
							$txt .= ")";
						} else {
							$txt .= " et prestation EDL associé)";
						}
						$row['remarque'] = "Transfert de DG impossible $txt";
						$row['nomLocataire'] = $resa->nomLocataire;
						$row['prenomLocataire'] = $resa->prenomLocataire;
						$row['dateFacture'] = "";
						$row['idReservation'] = $resa->id;

						$row['codeLocataire'] = $resa->codeLocataire;
						$row['etatReservation'] = $resa->etatReservation;
						$row['numeroChambre'] = $resa->numeroChambre;
						$row['residence'] = $resa->residence;

						$row['etatDG'] = 6;
						$row['rib'] = "";
						$row['nomRIB'] = "";
						$row['bic'] = "";
						$rows[] = $row;
					}
				}
			}
		}


		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/remboursement')
		->setVariables(array(
				"rows" => $rows,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);
		return $htmlOutput;
	}

	## load liste prelevements
	public function loadPrelevementListe($cData = array())
	{
		$rows = $this->loadPrelevements($cData);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/prelevement')
		->setVariables(array(
				"rows" => $rows,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);
		return $htmlOutput;
	}

	## load tab prelevements de la fiche locataire
	private function loadPrelevementTab($idResa)
	{
		$rows = $this->loadPrelevements(array('idResa' => $idResa));
		$resa = $this->getResaTable()->getResa($idResa);

		//on verifie si il a un alais loyer
		$aliasLoc = $this->getTableObjet('alias_locataires')->select(array('idLocataire' => $resa->idLocataire, 'type' => 'loyer'))->current();
		if (!$aliasLoc) {
			$resa->prelevementLoyer = 0;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/tabprelevement')
		->setVariables(array(
				"rows" => $rows,
				"interdirePrelevement" => $resa ? $resa->interdirePrelevement : "",
				"idResa" => $idResa,
				"prelevementLoyer" => $resa ? $resa->prelevementLoyer : null,
				"prelevementJourDuMois" => $resa ? $resa->prelevementJourDuMois : null,
				"alias" => $aliasLoc,
		));

		$htmlOutputCompte = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputCompte;
	}

	## load tab paiementEmail de la fiche locataire
	private function loadPaiementEmailTab($idResa)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

		$sm = $this->getServiceLocator();
		$resa = $this->getResaTable()->getResa($idResa);

		## Lecture de la liste des emails envoyés avec leur statut
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			$listeUrlToken	= $sm->get('Application\Model\UrlTokenTable')->getUrlTokenByResa($idResa);
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
		}

		## Lecture de la liste des paiements enregistrés pour cette réservation
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$paiements	= array();
		try {
			$resultSet	= $sm->get('Etudiant\Model\PaiementTable')->getPaiementsBy(array('idReservation' => $idResa));
			if ($resultSet) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa nbPaiements=");
				foreach ($resultSet as $row) {
					$paiements[$row->id]	= $row;
				}
			}
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/tabpaiementemail')
		->setVariables(array(
			"idResa" => $idResa,
			"resa" => $resa,
			"listeUrlToken" => $listeUrlToken,
			"paiements" => $paiements,
		));

		$htmlOutputCompte = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputCompte;
	}

	## activer/désactiver le prélevement
	public function validerprelevementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');
			$interdirePrelevementPost = $request->getPost('interdirePrelevement');
			$interdirePrelevement = 0;
			if ($interdirePrelevementPost == 'true') {
				$interdirePrelevement = 1;
			}

			$success = false;
			if ($idResa > 0) {
				$this->getResaTable()->updateResa(array('interdirePrelevement' => $interdirePrelevement), array('id' => $idResa));
				//Si activé alors que le prélevement est actif on le désactive et on cache l'onglet
				if ($interdirePrelevement == 1) {
					//on désactive le prélèvement
					$this->getResaTable()->updateResa(array('prelevementLoyer' => 0), array('id' => $idResa));
				}
				$success = true;
			}

			$view = new JsonModel(array(
						'success' => $success,
						  'htmlOPLoc' => $htmlOutputLoc,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## chargement de la liste des prelevements
	public function loadPrelevements($cData = array())
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$return =  array();
		$rows = array();

		$dateDebut = !empty($cData['dateDebut']) ? date('Y-m-d', strtotime($cData['dateDebut'])) : null;
		$dateFin = !empty($cData['dateFin']) ? date('Y-m-d', strtotime($cData['dateFin'])) : null;

		$idResa = !empty($cData['idResa']) ? $cData['idResa'] : null;

		$table = $this->getTableObjet('pile_loyer_historique');
		$select = $table->getSql()->select();

		$select->join('reservations', 'reservations.id = pile_loyer_historique.idReservation', array('numeroChambre', 'etat'), 'LEFT');
		$select->join('etat_reservation', 'etat_reservation.id = reservations.etat', array('etatReservation' => 'nom'), 'LEFT');

		$select->join('locataires', 'locataires.id = reservations.idLocataire', array('codeLocataire',
																		'nomLocataire' => 'nom',
																		'prenomLocataire' => 'prenom'), 'LEFT');

		$select->join('alias_locataires', 'alias_locataires.idLocataire = reservations.idLocataire', array(
																		'numCBCurrent' => 'numCB',
																		'typeCBCurrent' => 'typeCB',
																		'dateExpCBCurrent' => 'dateExpCB',
																		), 'LEFT');

		if ($dateDebut && $dateFin) {
			$select->where("pile_loyer_historique.datePrelevement BETWEEN '$dateDebut' AND '$dateFin' ");
		}
		$select->where(array('alias_locataires.type' => 'loyer'));
		if ($idResa) {
			$select->where(array('pile_loyer_historique.idReservation' => $idResa));
		}

		$rows1 = $table->selectWith($select);
		foreach ($rows1 as $row) {
			$row->source = "Historique";
			//si on a pas les infos CB dans l historique, on remplace par la carte en cours
			/*if(!$row->numCB) $row->numCB = $row->numCBCurrent;
			if(!$row->typeCB) $row->typeCB = $row->typeCBCurrent;
			if(!$row->dateExpCB) $row->dateExpCB = $row->dateExpCBCurrent;*/
			//on refait le format de la date expiratio CB, qui est sou form MMAA
			if ($row->dateExpCB) {
				$m = substr($row->dateExpCB, 0, 2);
				$y = substr($row->dateExpCB, 2, 2);
				$d = date('t', strtotime('01-'.$m.'-20'.$y));
				$row->dateExpCB = $d.'-'.$m.'-20'.$y;
			}
			if ($row->statutPaiement == 'ok') {
				if ($row->msg) {
					$row->resultatPrelevement = $row->msg;
				} else {
					$row->resultatPrelevement = "Réussi";
				}
			} elseif ($row->statutPaiement == 'ko') {
				if ($row->msg) {
					$row->resultatPrelevement = $row->msg;
				} else {
					$row->resultatPrelevement = "Echoué";
				}
				$row->causeRefus = $row->msgErreur;
			}
			$rows[] = $row;
		}

		## liste des loyer
		$table = $this->getTableObjet('pile_loyer');
		$select = $table->getSql()->select();

		$select->join('reservations', 'reservations.id = pile_loyer.idReservation', array('numeroChambre', 'etat', ), 'LEFT');
		$select->join('etat_reservation', 'etat_reservation.id = reservations.etat', array('etatReservation' => 'nom'), 'LEFT');

		$select->join('locataires', 'locataires.id = reservations.idLocataire', array('codeLocataire',
																		'nomLocataire' => 'nom',
																		'prenomLocataire' => 'prenom'), 'LEFT');

		$select->join('alias_locataires', 'alias_locataires.idLocataire = reservations.idLocataire', array('numCB', 'typeCB', 'dateExpCB'), 'LEFT');

		if ($dateDebut && $dateFin) {
			$select->where("pile_loyer.datePaiement BETWEEN '$dateDebut' AND '$dateFin' ");
		}
		$select->where(array('alias_locataires.type' => 'loyer'));
		if ($idResa) {
			$select->where(array('pile_loyer.idReservation' => $idResa));
		}

		$rows2 = $table->selectWith($select);
		foreach ($rows2 as $row) {
			$row->source = "Dans la pile";
			//on refait le format de la date expiratio CB, qui est sou form MMAA
			if ($row->dateExpCB) {
				$m = substr($row->dateExpCB, 0, 2);
				$y = substr($row->dateExpCB, 2, 2);
				$d = date('t', strtotime('01-'.$m.'-20'.$y));
				$row->dateExpCB = $d.'-'.$m.'-20'.$y;
			}
			$row->datePrelevement = $row->datePaiement;
			$rows[] = $row;
		}

		return $rows;
	}

	### fonction qui lit toutes les factures du mois par type
	public function lireFacturesDuMoisBredea($cData = array(), $idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$return =  array();
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					$return = $bredea->lireFacturesDuMois($cData);
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}

		return $return;
	}

	## load logs tab: fiche locataire
	// paramsLogs contient '$idResa' si '$isResa' = 1 ou '$idDp'
	private function loadLogsTab($idParamsLogs, $isResa)
	{
		$idLocataire = 0;
		$idResa = 0;
		if ($isResa == 1) {
			$logsResult = $this->getLogsTable()->getLogsByResa($idParamsLogs);
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idParamsLogs))->current();
			if ($resa) {
				$idLocataire = $resa->idLocataire;
				$idResa = $resa->id;
			}
		} else {
			$dp = $this->getTableObjet('domiciliations')->select(array("id" => $idParamsLogs))->current();
			$idLocataire = $dp->idLocataire;
			$logsResult = $this->getLogsTable()->getLogsByLocataire($idLocataire);
		}

		$result = $this->getTableObjet('user')->select();
		$gestionnaires = array();
		foreach ($result as $row) {
			$gestionnaires[$row->user_id] = $row->display_name;
		}

		$champs = $this->getAllFieldsListe($isResa);
		//on recupere toutes les valeurs select déjà
		$valeursSelect = array();
		$result = $this->getTableObjet('valeurs_select')->select();
		foreach ($result as $r) {
			$valeursSelect[$r->id] = $r->valeur;
		}

		$tableTL = $this->getTableObjet('type_logement');

		$rows = array();
		foreach ($logsResult as $log) {
			$dataBefore = json_decode($log->dataBefore, true);
			$dataAfter = json_decode($log->dataAfter, true);
			$infos = "";
			if (!empty($dataBefore) && !empty($dataAfter)) {
				//on contruit une phrase à partir de dateBefore et dataAfter
				if(strpos($log->operation, 'Changement logement') !== false) {
					//pour le logs changement logement, on affiche le type logement, logement et date de changement
					if(!empty($dataAfter['dateArrivee'])) {
						$valAfter = date('d-m-Y', strtotime($dataAfter['dateArrivee']));
						$infos .= "<b>Date de changement</b> : ".$valAfter."<br>";
					}

					if(!empty($dataBefore['idTypeLogementAttribue']) && !empty($dataAfter['idTypeLogementAttribue']) && $dataBefore['idTypeLogementAttribue'] != $dataAfter['idTypeLogementAttribue']) {
						$oldTL = $tableTL->select(array('id' => $dataBefore['idTypeLogementAttribue']))->current();
						$newTL = $tableTL->select(array('id' => $dataAfter['idTypeLogementAttribue']))->current();
						if($oldTL && $newTL) {
							$valBefore = $oldTL->nom;
							$valAfter = $newTL->nom;
							$infos .= "Modification du champ <b>".$champs['idTypeLogementAttribue']->nom." : de</b> $valBefore <b>vers</b> $valAfter <br>";
						}
					}

					if(!empty($dataBefore['numeroChambre']) && !empty($dataAfter['numeroChambre']) && $dataBefore['numeroChambre'] != $dataAfter['numeroChambre']) {
						$valBefore = $dataBefore['numeroChambre'];
						$valAfter = $dataAfter['numeroChambre'];
						$infos .= "Changement <b>logement </b> de $valBefore <b>vers</b> $valAfter<br>";
					}
					$log->infos = $infos;
					$rows[] = $log;
					continue;
				}
				foreach ($dataBefore as $cle => $val) {
					if (array_key_exists($cle, $champs) && array_key_exists($cle, $dataAfter)) {
						$valBefore = $val;
						$valAfter = $dataAfter[$cle];
						if ($champs[$cle]->idType == 3) {
							if (is_numeric($champs[$cle]->sourceListe)) {
								$valBefore = $valeursSelect[$valBefore];
								$valAfter = $valeursSelect[$valAfter];
							} elseif ($champs[$cle]->sourceListe && $champs[$cle]->sourceListe != 'user') {
								$rowSelectBefore = $this->getTableObjet($champs[$cle]->sourceListe)->select(array('id' => $valBefore))->current();
								$rowSelectAfter = $this->getTableObjet($champs[$cle]->sourceListe)->select(array('id' => $valAfter))->current();
								if ($rowSelectBefore && $rowSelectAfter) {
									if ($champs[$cle]->equivalentSql == "idPays") {
										$valBefore = $rowSelectBefore->pays;
										$valAfter = $rowSelectAfter->pays;
									} elseif ($champs[$cle]->equivalentSql == "idNationalite") {
										$valBefore = $rowSelectBefore->nationalite;
										$valAfter = $rowSelectAfter->nationalite;
									} else {
										$valBefore = $rowSelectBefore->nom;
										$valAfter = $rowSelectAfter->nom;
									}
								}
							}
						} elseif ($champs[$cle]->idType == 9 && $champs[$cle]->nature == "libre") {
							$options = explode(";", $champs[$cle]->options);
							$valBefore = !empty($options[$valBefore]) ? $options[$valBefore] : "";
							$valAfter = !empty($options[$valAfter]) ? $options[$valAfter] : "";
						} elseif ($champs[$cle]->idType == 2) {
							$valBefore = date('d-m-Y', strtotime($valBefore));
							$valAfter = date('d-m-Y', strtotime($valAfter));
						}
						$infos .= "Modification du champ <b>".$champs[$cle]->nom." : de</b> $valBefore <b>vers</b> $valAfter <br>";
					}
				}
				$log->infos = $infos;
			}
			$rows[] = $log;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/logstab')
		->setVariables(array(
				"rows" => $rows,
				"idResa" => $idParamsLogs,
				"gestionnaires" => $gestionnaires,
				"parcoursHtml" => $this->loadParcoursTab($idLocataire, $idParamsLogs, $isResa),
				"menagesHtml" => $this->loadMenagesTab($idResa),
				//"champs"	=> $champs,
		));

		$htmlOutputCompte = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutputCompte;
	}

	#######################################################################



	public function editlocatairearAction()
	{
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			$locForm = new LocataireARForm();

			$idLocataire = $request->getPost('id');

			$loc = $this->getLocatairesAccesResaTable()->getLocataire($idLocataire);
			
			if($loc->dateArrivee && substr($loc->dateArrivee,0,2) != '00'){
				$loc->dateArrivee = date('d-m-Y',strtotime($loc->dateArrivee));
			}
			if($loc->dateDepart && substr($loc->dateDepart,0,2) != '00'){
				$loc->dateDepart = date('d-m-Y',strtotime($loc->dateDepart));
			}

			//Liste des programmes
			$progs = $this->getProgrammeTable()->getProgrammesParent();
			$progList = array();
			foreach ($progs as $p) {
				$progList[$p->id] = $p->nom;
			}
			asort($progList);

			$locForm->get('idProgramme')->setAttribute('options', $progList);

			//sous prog
			$sp = array();
			if ($loc->idProgramme > 0) {
				$result = $this->getProgrammeTable()->getSousProgrammes($loc->idProgramme);
				//$result = $this->getProgrammeTable()->getSPDeCampagnes($loc->idProgramme, $ids);

				if ($result->count() <= 0) {
					$result = $this->getProgrammeTable()->getProgrammeById($loc->idProgramme);

					$sp[$result->id] = $result->nom;
				} else {
					foreach ($result as $r) {
						$sp[$r->id] = $r->nom;
					}
				}
			} else {
				$sp = false;
			}

			if (!empty($sp)) {
				asort($sp);
				$locForm->get('idSousProgramme')->setAttribute('options', $sp);
			}

			if($conf->mode == "HEC") {
				$locForm->get('codeLocataire')->setLabel('Code 3');
			}

			$locForm->bind($loc);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/locataireaccesresa')
			->setVariables(array(
					'form' => $locForm,
					'isGoal' => $loc->codeGoal ? 1 : 0,
					'lang' => 'fr_FR',
					'config' => $conf,
			));

			$htmlOutputLoc = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOPLoc' => $htmlOutputLoc,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function majlocatairearAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$form = new LocataireARForm();

			$idLocataire = $request->getPost('id');
			$loc = $this->getLocatairesAccesResaTable()->getLocataire($idLocataire);

			$form->bind($loc);
			$form->setInputFilter($loc->getInputFilter());
			$form->setData($request->getPost());

			$loc->exchangeArray($request->getPost());

			$this->getLocatairesAccesResaTable()->saveLocataire($loc);

			$htmlOutput = $this->loadModeAR();

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			return $view;
		}
	}

	public function deletearAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			foreach ($ids as $id) {
				$this->getLocatairesAccesResaTable()->deleteLocataire($id);
			}

			$htmlOutput = $this->loadModeAR();

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function uploadcsvAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : FILES=".json_encode($_FILES));
			//print_r($_FILES);
			$msg = "";

			$idProgramme = $request->getPost('idProgramme');
			$idSousProgramme = $request->getPost('idSousProgramme');
			$acces = $request->getPost('acces');

			if (!$idProgramme) {
				## Peut être facultatif en dehors de HEC
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				##$msg="<span class='error red'>Veuillez choisir un programme</span>";
				$idProgramme	= "";
			}
			if (!$idSousProgramme) {
				## Peut être facultatif en dehors de HEC
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				##$msg .="<br/><span class='error red'>Veuillez choisir un sous programme</span>";
				$idSousProgramme	= "";
			}
			if (!$acces) {
				$msg .= "<br/><span class='error red'>Veuillez choisir le mode d acces</span>";
			}


			if ($msg != "") {
				$view = new JsonModel(array(
						'success' => true,
						'passer' => 0,
						'msg' => utf8_encode($msg),
				));

				$view->setTerminal(true);
				return $view;
			}

			$msg = "";


			if (!is_dir(getcwd()."/public/data/import")) {
				mkdir(getcwd()."/public/data/import");
			}

			$folder = "./public/data/import";
			$passer = 0;//0:pas fourni , 1:pas chargé, 2:extension non valide, 3:uploader
			$namePJ = "";
			$elements = array();
			$idsPMS = array();

			if (isset($_FILES['listeCSV']) && $_FILES['listeCSV']['error'] == 0) {
				$passer = 1;

				$extension = pathinfo($_FILES['listeCSV']['name'], PATHINFO_EXTENSION);
				$filename = pathinfo($_FILES['listeCSV']['name'], PATHINFO_FILENAME);

				$namePJ = "liste_".date('Y-m-d-his').".".$extension;
				$allowed = array('csv');

				if (!in_array(strtolower($extension), $allowed)) {
					$passer = 2;
				} else {
					if (move_uploaded_file($_FILES['listeCSV']['tmp_name'], $folder.'/'.$namePJ)) {
						//upload réussi
						$passer = 3;
						$rows = $this->csvImport(getcwd().'/public/data/import/'.$namePJ, true, ';', '"', '\\');
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : namePJ=$namePJ nbRows=".$rows->count());


						//Nom, Prenom, @Mail1, @Mail2, Mobile, Programme, sousProgramme, CodeGoal,CodeSharepad, Acces
						$modeCompatible	= '';
						foreach ($rows as $row) {
							$header = array_keys($row);
							//$record = array_values($row);
							$record = $row;

							## Identification du mode ancien sans paramètrage implicite du nom des champs
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if (!$modeCompatible) {
								if (in_array('CODE_SHAREPAD', $header)) {
									$modeCompatible	= "HEC";
								} else {
									$modeCompatible	= "AUTO";
								}
							}
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : namePJ=$namePJ modeCompatible=$modeCompatible record=".json_encode($record));

							if ($modeCompatible == 'AUTO') {
								## Boucle de création des champs de data
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$data	= array();
								foreach ($header as $key) {
									$value	= !empty($record[$key]) ? trim($record[$key]) : "";
									if ($key == 'civilite') {
										if ($value == "1" || $value == "M" || $value == "Mr") {
											$value	= "1";
										} else {
											$value	= "2";
										}
									}
									$data[$key]	= $value;
								}

								## Vérification de l'unicité des codes
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$loc	= false;
								if ($data['codeLocataire']) {
									## On est en mode CodeLocataire qui doit être unique
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$loc = $this->getLocatairesAccesResaTable()->getLocataireByCodeLocataire($data['codeLocataire']);
								} elseif ($data['codeSharepad']) {
									## On est en mode CodeSharepad qui doit être unique
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$loc = $this->getLocatairesAccesResaTable()->getLocataireByCodeSharepad($data['codeSharepad']);
								} elseif ($data['codeGoal']) {
									## On est en mode CodeGoal qui doit être unique
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$loc = $this->getLocatairesAccesResaTable()->getLocataireByCodeGoal($data['codeGoal']);
								}
								if (!is_object($loc)) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : data=".json_encode($data));
									$locataireAR = new LocatairesAccesResa();
									$locataireAR->exchangeArray($data);
									$locataireAR->idProgramme = $idProgramme;
									$locataireAR->idSousProgramme = $idSousProgramme;
									$locataireAR->acces = $acces;
									$this->getLocatairesAccesResaTable()->saveLocataire($locataireAR);
								} else {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : data=".json_encode($data));
									$loc->idProgramme = $idProgramme;
									$loc->idSousProgramme = $idSousProgramme;
									$loc->acces = $acces;
									$this->getLocatairesAccesResaTable()->saveLocataire($loc);
								}
							} else {
								$nom = !empty($record['NOM']) ? trim($record['NOM']) : "";
								$prenom = !empty($record['PRENOM']) ? trim($record['PRENOM']) : "";
								$email = !empty($record['MAIL1']) ? trim($record['MAIL1']) : "";
								$emailHec = !empty($record['MAIL2']) ? trim($record['MAIL2']) : "";
								$telephoneMobile = !empty($record['MOBILE']) ? trim($record['MOBILE']) : "";
								$codeGoal = !empty($record['CODE_GOAL']) ? trim($record['CODE_GOAL']) : "";
								$codeSharepad = !empty($record['CODE_SHAREPAD']) ? trim($record['CODE_SHAREPAD']) : "";
								$codeLocataire = !empty($record['codeLocataire']) ? trim($record['codeLocataire']) : "";

								$civilite = !empty($record['CIVILITE']) ? trim($row['CIVILITE']) : "";
								$civilite = ($civilite && $civilite == "Mr") ? 1 : 2;



								$data = array('civilite' => $civilite,
												'nom' => $nom,
												'prenom' => $prenom,
												'email' => $email,
												'emailHec' => $emailHec,
												'codeSharepad' => $codeSharepad,
												'idProgramme' => $idProgramme,
												'idSousProgramme' => $idSousProgramme,
												'acces' => $acces,
												'idProgramme' => $idProgramme,
												'idSousProgramme' => $idSousProgramme,
												'codeLocataire' => $codeLocataire,
												);

								if(!empty($record['dateArrivee'])) $data['dateArrivee'] = trim($record['dateArrivee']);
								if(!empty($record['dateDepart'])) $data['dateDepart'] = trim($record['dateDepart']);


								//on verifie si existe
								$loc = $this->getLocatairesAccesResaTable()->getLocataireByCodeSharepad($codeSharepad);
								if(!$loc && $codeLocataire) {
									$loc = $this->getLocatairesAccesResaTable()->getLocataireByCodeLocataire($codeLocataire);
								}
								if (!$loc && ($codeSharepad || $codeGoal || $codeLocataire)) {
									$locataireAR = new LocatairesAccesResa();
									$locataireAR->exchangeArray($data);
									$this->getLocatairesAccesResaTable()->saveLocataire($locataireAR);
								} elseif ($loc) {
									$loc->idProgramme = $idProgramme;
									$loc->idSousProgramme = $idSousProgramme;
									$loc->acces = $acces;
									if ($email) {
										$loc->email = $email;
									}
									if ($emailHec) {
										$loc->emailHec = $emailHec;
									}
									if($codeLocataire) {
										$loc->codeLocataire = $codeLocataire;
									}
									$this->getLocatairesAccesResaTable()->saveLocataire($loc);
								}
							}
						}
					}
				}
			}

			$msg = "";
			switch ($passer) {
				case 0: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 1: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 2: $msg = "<span class='error red'>Erreur extension(seulement csv)</span>";
					break;
				case 3: $msg = "<span class='success green'>Fichier uploader, veuillez cliquer sur le bouton rafraichir</span>";
					break;
			}



			$view = new JsonModel(array(
					'success' => true,
					'passer' => $passer,
					'msg' => utf8_encode($msg),
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	### fonction qui tout les infos resa, locataire de Bredea de tout les locataires
	public function readAllBredeaInfos($idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$return =  array();
		//return $return;
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);
					$return['demandes'] = $bredea->lireTout('demande');
					$return['resas'] = $bredea->lireTout('resa');
					$return['dossiers'] = $bredea->lireTout('dossier');
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}

		return $return;
	}

	//recharger la ligne modifier dans la liste
	public function getlisterowAction()
	{
		//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$idResa = (int) $request->getPost('idResa');
			$idListe = (int) $request->getPost('idListe');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idListe=$idListe");

			$resa = $this->getResaTable()->getListe($idResa)->current();

			$champs = array();
			$ids = array();
			$liste = array();
			$isResa = true;

			$ilYaDesChampsDynamiques = false;//on verifie si il ya des champs dynamique dans la liste
			if ($idListe > 0) {
				## Affichage des champs dans l'ordre des champs dans la table champs_liste
				$champsListe = $this->getListesTable()->getListAllFields($idListe);
				foreach ($champsListe as $champ) {
					//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe codeBase=$champ[codeBase] codeDyn=$champ[codeDyn]");
					if ($champ[codeBase]) {
						## Lecture du champ de base
						## ~~~~~~~~~~~~~~~~~~~~~~~~
						$r = $this->getListesTable()->getListeField($idListe, $champ[codeBase])->current();
						$champs[] = $r;
					} elseif ($champ[codeDyn]) {
						$r = $this->getListesTable()->getListeDynamiqueField($idListe, $champ[codeDyn])->current();
						##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".print_r($r,1));
						$champs[] = $r;
						$ilYaDesChampsDynamiques = true;
					}
				}
				$listeRes = $this->getListesTable()->getListe($idListe);
			}

			$extraLoc = array();
			if ($ilYaDesChampsDynamiques) {
				$extraLoc = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($resa->idLocataire, $adapter, $idResa);
			}
			//echo "peak_memory_usage = " . memory_get_peak_usage(true) . "<br>";
			if ($resa->idNouvelleResa) {
				$nr = $this->getResaTable()->getResa($resa->idNouvelleResa);
				if ($nr && $nr->numDossier == $resa->numDossier) {
					$resa->dateDepart = $resa->dateDepart;
				} elseif ($nr && $nr->etat == 15) {
					//si la resa est en cours de changement
					$resa->etatReservation .= " - en cours de changement ".$nr->numeroChambre."";
				}
				//si liste de changement de logement, on mis la date de depart de la nouvelle resa
				if ($listeRes->idType == 6) {
					$resa->dateDepart = $nr->dateDepart;
				}
			}


			$resaArray = get_object_vars($resa);
			$row = array_merge($extraLoc, $resaArray);
			//print_r($row);exit();

			$rowData = array();
			$i = 1;//on commence de 1, pour aviter le premier colonne ou il ya le checkbox
			foreach ($champs as $t1) {
				$codeChamp = $t1->code;
				$val = (array_key_exists($codeChamp, $row) ? $row[$codeChamp] : '');

				//$row = get_object_vars($resa);
				if (substr($t1->code, 0, 4) == "date" || $t1->idType == 2) {
					if (date('Y', strtotime($val)) > 1980) {
						if ($t1->code == "dateDemandeReservation") {
							$val = date('d-m-Y H:i:s', strtotime($val));
						} else {
							$val = date('d-m-Y', strtotime($val));
						}
					}
				} elseif ($t1->code == "boursier" || $t1->code == "prbSante") {
					if ($t1->code == "boursier") {
						$val = $resa->attestationBourseCheck ? "Oui" : "Non";
					} else {
						$val = $resa->certificatMedicalCheck ? "Oui" : "Non";
					}
				} elseif ($t1->code == "attestationBourse" || $t1->code == "certificatMedical") {
					if ($row[$t1->code] != "" && file_exists(getcwd()."/public/docs/locataires/".$row['idLocataire']."/".$row[$t1->code])) {
						$val = "<a href=".$this->getBaseUrl()."/docs/locataires/".$row['idLocataire']."/".$row[$t1->code]." target='_blank'>";
						$val .= $row[$t1->code];
						$val .= "</a>";
						$val .= "<span class='apercu'><i class='fa fa-eye red fa-2x'></i>";
						$val .= "<input type='hidden' name='fileLink' class='idFileLink' value=".$row['idLocataire']."/".$row[$t1->code]." />";
						$val .= "</span>";
					} else {
						$val = $row[$t1->code];
					}
				} elseif ($t1->code == "certificatAssur") {
					if ($row['certificatAssur'] != "" && file_exists(getcwd()."/public/docs/locataires/".$row['idLocataire']."/".$row['certificatAssur'])) {
						$val = "<a href=".$this->getBaseUrl()."/docs/locataires/".$row['idLocataire']."/".$row['certificatAssur']." target='_blank'>";
						$val .= $row['certificatAssur'];
						$val .= "</a>";
						$val .= "<span class='apercu'><i class='fa fa-eye red fa-2x'></i>";
						$val .= "<input type='hidden' name='fileLink' class='idFileLink' value=".$row['idLocataire']."/".$row['certificatAssur']." />";
						$val .= "</span>";
					} else {
						$val = $row['certificatAssur'];
					}
				} elseif ($t1->idType == 4) {
					if ($row[$t1->code] != "" && file_exists(getcwd()."/public/docs/locataires/".$row['idLocataire']."/".$row[$t1->code])) {
						$val = "<a href=".$this->getBaseUrl()."/docs/locataires/".$row['idLocataire']."/".$row[$t1->code]." target='_blank'>";
						$val .= $row[$t1->code];
						$val .= "</a>";
						$val .= "<span class='apercu'><i class='fa fa-eye red fa-2x'></i>";
						$val .= "<input type='hidden' name='fileLink' class='idFileLink' value=".$row['idLocataire']."/".$row[$t1->code]." />";
						$val .= "</span>";
					} else {
						$val = "";
					}
				} elseif ($t1->code == "statutAssur") {
					$selected1 = "";
					$selected2 = "";
					$statut = "";
					if ($row[$t1->code] == 1) {
						$statut = ("Refusée");
						$selected1 = "selected";
						$selected2 = "";
					} elseif ($row[$t1->code] == 2) {
						$statut = ("Validée");
						$selected2 = "selected";
						$selected1 = "";
					} else {
						$statut = ("Non traitée");
					}
					$val = "<span class='statutAA' id='statut_".$row['idReservation']."'>".$statut."</span>";
					$val .= "<span class='hide'>|</span>";
					$val .= "<select name='statut' class='idStatut'>";
					$val .= "<option value=''>".("Non traitée")."</option>";
					$val .= "<option value='1' ".$selected1.">".("Refusée")."</option>";
					$val .= "<option value='2' ".$selected2.">".("Validée")."</option>";
					$val .= "<select>";
				} elseif ($t1->code == "EtatDesLieux") {
					$edlCheck = $row["EtatDesLieux"] ? "checked='checked'" : '';
					$edlVal = $row["EtatDesLieux"] ? $row["EtatDesLieux"] : "0";
					$val = "<input type='checkbox' $edlCheck value='$edlVal' class='edlChk' id='edl_".$row['idReservation']."' data-id='".$row['idReservation']."' data-type='edl' /> ";
					$val .= "<span class='edltxt_".$row['idReservation']."'>";
					$val .= $row["EtatDesLieux"] ? "Retour EDL OK" : "Non Retour";
					$val .= "</span>";
				} else {
					$numero = str_replace('typeLogement', '', $t1->code);
					if (is_numeric($numero)) {
						$choix = $this->getChoixTable()->getChoixByResaNumero($row['idReservation'], $numero);
						if ($choix) {
							$val = $choix->typeLogement;
						}
					}
				}
				$rowData[$i] = $val;
				$i++;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : rowData=".json_encode($rowData));

			$view = new JsonModel(array(
						'success' => true,
						'rowData' => json_encode($rowData),
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function getEtatICCollective()
	{

		## listes des etatIC
		$icResult = $this->getEtatIntercontratTable()->select();
		$allEtatsICArray = array();
		foreach ($icResult as $ic) {
			$allEtatsICArray[$ic->id] = $ic;
		}


		$tableIC = $this->getTableObjet('intercontrat_pieces_collectives');
		$select = $tableIC->getSql()->select();
		$select->join('logements', 'intercontrat_pieces_collectives.idLogement = logements.id', array('idBatiment', 'idLog' => 'id', 'nom', 'numero'));
		$icvResult = $tableIC->selectWith($select);

		$batLogColl = array();
		$icvArray = array();
		$firstICVArray = array();//on y stock le premier etat par logement, pour connaitre le debut de rotation
		foreach ($icvResult as $icv) {
			$title = $icv->duree.' j '.$allEtatsICArray[$icv->idEtat]->nom;
			$icv->title = $title;
			$icvArray[$icv->idLogement] = $icv;
			if (!array_key_exists($icv->idLogement, $firstICVArray)) {
				$firstICVArray[$icv->idLogement] = $icv;
			}

			$batLogColl[$icv->idBatiment] = $icvArray;
		}
		return $batLogColl;
	}

	private function loadResaState($idListe)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe");
		$conf = $this->getConfigurationTable()->getConfig(1);
		$resaStateArr	= array();
		$resaStateObj	= $this->getTableObjet('liste_state')->select(array('idListe' => $idListe))->current();
		if ($resaStateObj) {
			$resaState	= json_decode($resaStateObj->data, 1);
			$configFilters = array();
			if ($resaStateObj->configFilters) {
				$configFilters = json_decode($resaStateObj->configFilters, 1);
			}
			if ($resaState && array_key_exists('filter', $resaState)) {
				if (!empty($configFilters) && $conf->filtresDyn == 1) {
					$resaStateArr = $this->getConfigFiltersTable()->reGenerateListeState($resaState, $configFilters);
				} else {
					$resaStateArr	= $resaState;
				}
			} else {
				## Peut-être l'ancien format
				## ~~~~~~~~~~~~~~~~~~~~~~~~~

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe oldFormat");
				$resaStateArr['filter']	= array();

				$champs	= array();
				$champsListe = $this->getListesTable()->getListAllFields($idListe);
				if ($champsListe) {
					$typeSelects	= array("1" => "text", "2" => "date", "3" => "select", "5" => "number", "6" => "text", "12" => "number", "13" => "number");
					$themes2types	= array("1" => "loc", "2" => "resa", "3" => "resa", "6" => "resa");
					foreach ($champsListe as $champ) {
						#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe codeBase=$champ[codeBase] codeDyn=$champ[codeDyn]");
						if ($champ['codeBase']) {
							## Lecture du champ de base
							## ~~~~~~~~~~~~~~~~~~~~~~~~
							$r = $this->getListesTable()->getListeField($idListe, $champ['codeBase'])->current();

							$typeSearch	= array_key_exists($r->idType, $typeSelects) ? $typeSelects[$r->idType] : 'text';
							$resaStateArr['filter'][$r->code]	= array("search" => "", "type" => $typeSearch);
						} elseif ($champ['codeDyn']) {
							$r = $this->getListesTable()->getListeDynamiqueField($idListe, $champ['codeDyn'])->current();

							$typeSearch	= $typeSelects[$r->idType];
							$resaStateArr['filter'][$r->code]	= array("search" => "", "type" => $typeSearch);
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe oldFormat jsonResa=".json_encode($resaStateArr));
			}
		}
		return	$resaStateArr;
	}

	public function afficherAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$ids1 = $ids2 = $ids3 = null;
		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			//echo "debut action, memory now at " . memory_get_usage(true) . "<br>";
			//option perdue et duree relance
			$tableC = new Tables('configuration', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$params = $tableC->getTable()->select()->current();

			$optionPerdue = '3';//+3 jours pardefaut
			if ($params->option_perdue) {
				$optionPerdue = $params->option_perdue;
			}
			$dureeRelance = '3';//+3 jours pardefaut
			if ($params->envoie_relance) {
				$dureeRelance = $params->envoie_relance;
			}

			## Lecture des paramètres
			## ~~~~~~~~~~~~~~~~~~~~~~
			##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : post=".json_encode($request->getPost()));
			$isPlanning = null;
			$idCss = null;
			$idListe = (int) $request->getPost('id');
			$limit = (int) $request->getPost('limit');
			$isPlanning = $request->getPost('isPlanning');
			$idCss = $request->getPost('idCss');
			$searchName = $request->getPost('searchName', '');
			$searchPrenom = $request->getPost('searchPrenom', '');
			$searchCodeLocataire = $request->getPost('searchCodeLocataire', '');
			$searchNumeroChambre = $request->getPost('searchNumeroChambre', '');
			$searchArchive = $request->getPost('searchArchive', '');
			$rechercheStricteNom = $request->getPost('rechercheStricteNom', '');
			$rechercheStrictePrenom = $request->getPost('rechercheStrictePrenom', '');
			$rechercheStricteDateNaissance = $request->getPost('rechercheStricteDateNaissance', '');
			$rechercheStricteArchive = $request->getPost('rechercheStricteArchive', '');
			$degroupe = $request->getPost('degroupe', '');
			if (empty($limit) || $limit < 0 || $limit > 500) {
				$limit = 500;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isPlanning=$isPlanning idListe=$idListe limit=$limit".($searchName ? " searchName=$searchName" : "").($rechercheStricteNom ? " rechercheStricteNom=$rechercheStricteNom" : "")." Version serverSide");

			## filtre bandeau
			$sessFB = new Container('filtreBandeau');
			$FiltresBandeau = isset($sessFB->filtres) ? $sessFB->filtres : array();

			$champs = array();
			$ids = array();
			$liste = array();
			$isResa = false;
			$ids2 = $ids2 = $ids3 = array();

			// $ilYaDesChampsDynamiques = false;//on verifie si il ya des champs dynamique dans la liste
			if ($idListe > 0) {
				$isResa = true;
				$listeRes = $this->getListesTable()->getListe($idListe);
				if ($listeRes) {
					$liste['id'] = $listeRes->id;
					$liste['nom'] = $listeRes->nom;
					$liste['idEtat'] = $listeRes->idEtat;
					$liste['idType'] = $listeRes->idType;
					$liste['flag'] = $listeRes->flag;
					$liste['indicateur'] = $listeRes->indicateur;
					$liste['stats'] = $listeRes->stats;
					if ($_SESSION['USERDROIT']['liste-input-mode-liste-btn-delete-any'] == 'R') {
						## Lorsque le profil permet de supprimer n'importe quelle liste
						$liste['canDelete'] = '1';
					} else {
						if ($listeRes->idUser == $gestId) {
							//il a le droit de supprimer
							$liste['canDelete'] = '1';
						} else {
							$liste['canDelete'] = '0';
						}
					}
				}
				$typeListe	= $liste['idType'];
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe liste=".json_encode($liste));

				## Lecture des descriptions des champs des listes
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$jsonResaDatatableState = $request->getPost('jsonResaDatatableState', array());
				$jsonResaDatatableFrom  = 'POST';
				if (empty($jsonResaDatatableState)) {
					$jsonResaDatatableState = $this->loadResaState($idListe);
					$jsonResaDatatableFrom  = 'BDD';
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe jsonResaDatatableState($jsonResaDatatableFrom)=".json_encode($jsonResaDatatableState));
				$jsonResaDatatableFilter        = $jsonResaDatatableState['filter'];

				## Valeurs uniques pour les différents selects
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$selectOptions	= array();

				## Constitution d'une liste des lignes
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$rowsAll	= array();

				if ($jsonResaDatatableFilter) {
					## Initialisation de la liste des champs de la liste des réservations
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$formFields     = $this->getResaFields($idListe, $jsonResaDatatableFilter);

					## Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$listeChampsAffiches    = $this->getlisteChampsAffiches($jsonResaDatatableFilter, $formFields);
					##AK_DEBUG syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffiches));

					// var_dump($listeChampsAffiches);die();
					## Version rapide de la lecture de la BDD
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
					$where	= ($isPlanning && $typeListe == 1) ? array("reservations.etat" => 1) : array();
					$residences = [];
					$gestionnaire_residences = $this->getTableObjet('gestionnaire_residences')->select(array('idGestionnaire' => $gestId));
					foreach ($gestionnaire_residences as $row) {
						$residences[] = $row->idResidence;
					}

					// var_dump("eee");die();

					//array_push($where, "batiments.idResidence IN (?)", implode(',',$residences));
					//array_push($where, "batiments.idResidence IN (".implode(',',$residences).")");
					if (count($residences) > 0) {
						if(array_key_exists('typeLogement1', $listeChampsAffiches)) {
							$subQueryTL = "IF( (SELECT ct.idTypeLogement FROM choix_typelogement as ct WHERE reservations.id = ct.idReservation AND ct.numeroChoix = 1 LIMIT 1),(SELECT batiments.idResidence FROM choix_typelogement as ct2 LEFT JOIN typelogement_batiment ON ct2.idTypeLogement = typelogement_batiment.idTypeLogement LEFT JOIN batiments ON typelogement_batiment.idBatiment = batiments.id WHERE reservations.id = ct2.idReservation AND ct2.numeroChoix = 1 LIMIT 1) IN (".implode(',', $residences).") , 1=1)";

							$subQueryR = "IF( (SELECT ct.idResidence FROM choix_typelogement as ct WHERE reservations.id = ct.idReservation AND ct.numeroChoix = 1 LIMIT 1),(SELECT ct2.idResidence FROM choix_typelogement as ct2 WHERE reservations.id = ct2.idReservation AND ct2.numeroChoix = 1 LIMIT 1) IN (".implode(',', $residences).") , $subQueryTL)";
						} else {
							$subQueryR = "1=1";
						}

						$subQuery1 = "IF(reservations.residenceOrientation > 0,reservations.residenceOrientation IN (".implode(',', $residences)."),$subQueryR )";
						//array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',',$residences)."),1=1 )");
						array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',', $residences)."),$subQuery1 )");
					}

					## filtresBandeau
					if (!empty($FiltresBandeau)) {
						if (!empty($FiltresBandeau['idResidence'])) {
							$in = implode(',', $FiltresBandeau['idResidence']);
							//array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".$in."),1=1 )");
							array_push($where, "batiments.idResidence IN (".$in.")");
						}
						if (!empty($FiltresBandeau['idBatiment'])) {
							$in = implode(',', $FiltresBandeau['idBatiment']);
							//array_push($where, "IF(reservations.idLogement > 0,batiments.id IN (".$in."),1=1 )");
							array_push($where, "batiments.id IN ($in)");
						}
						if (!empty($FiltresBandeau['idCampagne'])) {
							$in = implode(',', $FiltresBandeau['idCampagne']);
							array_push($where, "reservations.idCampagne IN ($in)");
						}
						if (!empty($FiltresBandeau['idProgramme'])) {
							$in = implode(',', $FiltresBandeau['idProgramme']);
							array_push($where, "reservations.idProgramme IN ($in)");
						}
						if (!empty($FiltresBandeau['idSousProgramme'])) {
							$in = implode(',', $FiltresBandeau['idSousProgramme']);
							array_push($where, "reservations.idSousProgramme IN ($in)");
						}
					}

					$campagnesDeGest = [];
					## on vérifie si on a le droit d'attribution campagne, si oui on controle les campagnes sinon on affiche tout
					if($_SESSION['USERDROIT']['user-campagnes'] == 'W'){
						$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
						foreach ($gestionnaire_campagnes as $row) {
							$campagnesDeGest[] = $row->idCampagne;
						}
					}
					if (!empty($campagnesDeGest)) {
						array_push($where, "IF(reservations.idCampagne > 0,reservations.idCampagne IN (".implode(',', $campagnesDeGest)."),1=1 )");
					}

					//print_r($where);exit();
					$rowsAll = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where, array('config' => $conf, 'degroupe' => $degroupe));
					if($typeListe == 18) {
						//pour la liste des prestation calculé, on a besoin de une ligne de present + une ligne prestations_to_resa si existe
						$rowsAll_2 = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where, array('config' => $conf, 'cible' => 'presents'));
						$rowsAll = array_merge($rowsAll, $rowsAll_2);
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe rows.count=".count($rowsAll));

					// var_dump($rowsAll);die();

					## Constitution de la liste des options
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					/*if ($rowsAll) {
						foreach ($rowsAll as $_key => $_row) {
							foreach ($_row as $_colName => $_value) {
								if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
									$_options	= $selectOptions[$_colName];
									if(trim($_value ==""))$_value = 'null';
									if (!$_options || !in_array($_value, $_options)) {
										if($conf->filtresDyn == 1 && ($_colName == 'idUser' || $listeChampsAffiches[$_colName]['sourceListe']=='user')){
											$filterVal = $this->getConfigFiltersTable()->getSelectFieldFilterValue($_colName,$idListe,'reservation');
											if($filterVal){
												if($filterVal == $_value){
													$selectOptions[$_colName][] = $_value;
												}
											}else{
												$selectOptions[$_colName][] = $_value;
											}
										}else{

										}

									}
								}
							}
						}
					}*/
					if ($rowsAll) {
						foreach ($rowsAll as $_key => $_row) {
							foreach ($_row as $_colName => $_value) {
								if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
									$_options	= $selectOptions[$_colName];
									if (trim($_value == "")) {
										$_value = 'null';
									}
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
									$_options	= $selectOptions[$_colName];
									if (trim($_value == "")) {
										$_value = 'null';
										$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
										if (!$_options || !in_array($_value, $_options)) {
											$selectOptions[$_colName][] = $_value;
										}
									} elseif($_value) {
										$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
										if(!empty($valsArr)) {
											foreach($valsArr as $k => $v) {
												$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
												if (!$_options || !in_array($v, $_options)) {
													$selectOptions[$_colName][] = $v;
												}
											}
										}
									}
								}
							}
						}
					}

					## Type liste indicateurs qui groupes toutes les listes de ce type
					if ($typeListe == 24) {
						$selectOptions['nomIndicateur'] = $this->getListesTable()->getAllListesIndicateurs($gestId, $idProfile, $adapter);
					}

					## Tri de ces options dans l'ordre alphabétique
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					foreach ($selectOptions as $_colName => $_options) {
						sort($selectOptions[$_colName], SORT_STRING);
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe selectOptions=".json_encode($selectOptions));
				}
				$champsNonModifiables = array(
								'idReservation', 'idLocataire', 'idPMS',
								'nomLocataire', 'prenomLocataire', 'etatReservation',
								'campagne', 'programmeEcole', 'sousProgrammeEcole', 'programme', 'sousProgramme',
								'batiment', 'residence',
								'etatIntercontrat',
								'typeLogement1', 'typeLogement2', 'typeLogement3', 'typeLogement4', 'typeLogementAttribue', 'prelevementLoyer',
								'clesPrincipale',
							);

				//on y ajoute les champs non modifiable par profil
				$champsNonModifiableParProfile = $this->getChampCatTable()->getChampsDeProfile($idProfile);

				if ($typeListe == 2) {
					$intercontrats = $this->getRealEtatintercontratTable()->fetchAll();
				}

				$modeles = array();
				$modelesRows = $this->getTableObjet('type_modeles_docs')->select(array('active' => 1, 'imprimableEnLot' => 1));
				foreach ($modelesRows as $mod) {
					$modeles[] = $mod;
				}

				// print_r($selectOptions);
				// die();
				try {
					$prestationRegul = $this->getChargesTable()->getAllPrestationsRegul();
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : getAllPrestationsRegul Exception=".$ex->getMessage());
					echo $ex->getMessage();
				}

				$typesCharges = $this->getChargesTable()->fetchAllChargesTypes();
				$prestationsProv = $this->getChargesTable()->getAllPrestationsProv();

				// si la liste est de type stats, récupérer les modèles qui lui sont attribués
				$modelesStats = array();
				if ($liste['stats'] == '1') {
					$modelesListes = $this->getTableObjet('stats_modeles_liste')->select(array('idListe' => $idListe, 'tableListes' => 'listes'))->toArray();
					if (count($modelesListes) > 0) {
						foreach ($modelesListes as $key => $modeleListe) {
							$mo = $this->getTableObjet('stats_modeles')->select(array('id' => $modeleListe['idModele']))->current();
							$modelesStats[] = $mo;
						}
					}
				}

				$campagnesUserCoLiens = [];
				$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
				foreach ($gestionnaire_campagnes as $gestionnaire_campagne) {
					$campagne = $this->getTableObjet('campagnes')->select(array('id' => $gestionnaire_campagne->idCampagne))->current();
					if ($campagne->archive == '1') {
						continue;
					}

					$modeCampagne = $this->getTableObjet('modes_campagne')->select(array('idCampagne' => $campagne->id, 'idMode' => '2'))->current();

					if ($modeCampagne) {
						$campagneUserCo = (object) array();
						$campagneUserCo->nom = $campagne->nom;
						$campagneUserCo->urlAcces = $modeCampagne->urlAcces;
						$campagnesUserCoLiens[] = $campagneUserCo;
					}
				}

				// syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe typeListe=$typeListe intercontrats=".json_encode($intercontrats));
				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
					->setTemplate('reservation/liste/afficher')
					->setVariables(array(
					'rows' 		=> array(),
					'isResa'	=> $isResa,
					'isPlanning'	=> $isPlanning,
					'idListe'	=> $idListe,
					'typeListe'	=> $typeListe,
					//'locFields' 	=> isset($formFields) ? $formFields['locFields'] : [],
					'resaFields' 	=> isset($formFields) ? $formFields['resaFields'] : [],
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'		=> 1,
					'intercontrats' => isset($intercontrats) ? $intercontrats : null,
					'jsonResaDatatableState' => $jsonResaDatatableState,
					'champsNonModifiables'	=> $champsNonModifiables,
					'selectOptions'	=> $selectOptions,
					'config' => $conf,
					'searchName' => $searchName,
					'searchPrenom' => $searchPrenom,
					'searchCodeLocataire' => $searchCodeLocataire,
					'searchNumeroChambre' => $searchNumeroChambre,
					'searchArchive' => $searchArchive,
					'rechercheStricteNom' => $rechercheStricteNom,
					'rechercheStrictePrenom' => $rechercheStrictePrenom,
					'rechercheStricteDateNaissance' => $rechercheStricteDateNaissance,
					'rechercheStricteArchive' => $rechercheStricteArchive,
					'typesSuivis' => $this->getListeTypesSuivis(),
					'modeles' => $modeles,
					'prestationRegul' => $prestationRegul,
					'typesCharges' => $typesCharges,
					'prestationsProv' => $prestationsProv,
					'residences' =>  $this->getResidencesTable()->fetchByGest($gestId),
					'typesCatalogue' => $this->getCatalogueTable()->getTypesCatalogueListe('autre'),
					'champsNonModifiableParProfile' => $champsNonModifiableParProfile,
					'modelesStats' => $modelesStats,
					'liste' => $liste,
					'campagnesUserCoLiens' => $campagnesUserCoLiens,
					'campagnes' => $this->getCampagneTable()->getCampagnesModeBy(),
					'prestationsCheckin' => $this->getPrestationsCheckinTable()->fetchAll(),
					'campagnesRows' => $this->getCampagneTable()->getCampagnesByTypeCode(null, $gestId),
					));
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : apres htmlViewPart");

				$htmlOutput = $this->getServiceLocator()
					->get('viewrenderer')
					->render($htmlViewPart);

				$view = new JsonModel(array(
					'success' => true,
					'champs' => $listeChampsAffiches,
					'liste' => $liste,
					'htmlOP' => $htmlOutput,
					));
				$view->setTerminal(true);
				return $view;
			}

			// if (0) {
			// 	if($idListe > 0){
			// 		if (1) {
			// 			## Affichage des champs dans l'ordre des champs dans la table champs_liste
			// 			$champsListe = $this->getListesTable()->getListAllFields($idListe);
			// 			foreach ($champsListe as $champ){
			// 				//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe codeBase=$champ[codeBase] codeDyn=$champ[codeDyn]");
			// 				if ($champ['codeBase']) {
			// 					## Lecture du champ de base
			// 					## ~~~~~~~~~~~~~~~~~~~~~~~~
			// 					$r = $this->getListesTable()->getListeField($idListe, $champ['codeBase'])->current();

			// 					##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".print_r($r,1));
			// 					$champs[]=$r;

			// 					$ids[] = $r->code;
			// 					if($r->idTheme == 2){
			// 						$isResa = true;
			// 					}
			// 					if($r->idTheme == 1){
			// 						$ids1[] = $r->code;
			// 					}elseif($r->idTheme == 2){
			// 						$ids2[] = $r->code;
			// 					}elseif($r->idTheme == 3){
			// 						$ids3[] = $r->code;
			// 					}

			// 				} elseif ($champ['codeDyn']) {

			// 					$r = $this->getListesTable()->getListeDynamiqueField($idListe, $champ['codeDyn'])->current();
			// 					##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : champ=".print_r($r,1));
			// 					$champs[]=$r;

			// 					$ids[] = $r->code;
			// 					$ids1[] = $r->code;
			// 					$ilYaDesChampsDynamiques =true;
			// 				}
			// 			}
			// 		} else {
			// 			$result = $this->getListesTable()->getListeFields($idListe);
			// 			foreach ($result as $r){
			// 				$champs[]=$r;
			// 				$ids[] = $r->code;
			// 				if($r->idTheme == 2){
			// 					$isResa = true;
			// 				}
			// 				if($r->idTheme == 1){
			// 					$ids1[] = $r->code;
			// 				}elseif($r->idTheme == 2){
			// 					$ids2[] = $r->code;
			// 				}elseif($r->idTheme == 3){
			// 					$ids3[] = $r->code;
			// 				}

			// 			}
			// 			//champs dynamiques
			// 			$dFields = $this->getListesTable()->getListeDynamiqueFields($idListe);
			// 			foreach ($dFields as $f) {
			// 				$champs[] = $f;
			// 				$ids[] = $f->code;
			// 				$ids1[] = $f->code;
			// 			}
			// 			if($dFields->count()>0){
			// 				$ilYaDesChampsDynamiques =true;
			// 			}
			// 		}
			// 	}
			// 	syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nbIds=".count($ids)." ids=".json_encode($ids));

			// 	$data = "{}";
			// 	$dateFilter = "";
			// 	$numberFilter = "";

			// 	if($idListe > 0){
			// 		$session = new Container('ListeIds');
			// 		$session->ids1 = $ids1;
			// 		$session->ids2 = $ids2;
			// 		$session->ids3 = $ids3;

			// 		//print_r($champs);
			// 		//liste state
			// 		$tableObj_liste_state = new Tables('liste_state',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			// 		$row = $tableObj_liste_state->getTable()->select(array('idListe'=>$idListe))->current();

			// 		$session = new Container('listeState');

			// 		if($row){
			// 			$data = $row->data;
			// 			$dateFilter = $row->dateFilter;
			// 			$numberFilter = $row->numberFilter;
			// 		}

			// 		//le cas rafraichir
			// 		$refresh = $request->getPost('refresh');

			// 		//echo "$idListe -- ".$session->idListe." ";
			// 		//print_r($session->data);exit();
			// 		if($session->idListe && $session->idListe == $idListe && $refresh == '1'){
			// 			$data = $session->data;
			// 			$dateFilter = $session->dateFilter;
			// 			$numberFilter = $session->numberFilter;

			// 		}

			// 		$sessListe = new Container('liste');//pour ne pas executer la requete sql a chaque fois, on stock le result dans la session
			// 		//si on rafraichit la liste, alors, on garde plus la session
			// 		if($refresh == '1'){
			// 			$sessListe->rows = null;
			// 		}


			// 		if($isResa){
			// 			$availableFields = array();
			// 			$tables = array();
			// 			foreach($champs as $chm){
			// 				if($chm->table){

			// 					if($chm->sourceListe){
			// 						$table = $chm->sourceListe;
			// 					}else{
			// 						$table = $chm->table;
			// 					}
			// 					$tables[$table] = $table;

			// 				}
			// 				$availableFields[] = $chm->code;
			// 			}

			// 			$tablesSql = array();//tables avec champs de chaque table
			// 			foreach($tables as $tbl){
			// 				foreach($champs as $chm){
			// 					if($chm->sourceListe){
			// 						$table = $chm->sourceListe;
			// 					}else{
			// 						$table = $chm->table;
			// 					}
			// 					if($tbl == $table){
			// 						$champsDeTable[$chm->code] = $chm->equivalentSql;
			// 					}
			// 				}
			// 				$tablesSql[$tbl] = $champsDeTable;
			// 			}
			// 		}

			// 		$timestart = microtime(true);
			// 		$where = array();
			// 		if(!empty($liste['idType']) && $liste['idType'] == 5){
			// 			//liste archive
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'1');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 3){
			// 			//liste arriver
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'3','predicat'=>'IN');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 2){
			// 			//liste menage
			// 			$where[] = array('table'=>'reservations','champ'=>'idIntercontrat','valeur'=>'NOTNULL');
			// 			$where[] = array('table'=>'reservations','champ'=>'idIntercontrat','valeur'=>'5','predicat'=>'NOTEQUALTO');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 4){
			// 			//liste depart
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'7');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 1){
			// 			//liste demandes
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'1');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 7){
			// 			//liste groupes
			// 			$where[] = array('table'=>'reservations','champ'=>'idGroupeResa','valeur'=>'NOTNULL');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		//liste des changement de logement demandé
			// 		if(!empty($liste['idType']) && $liste['idType'] == 6){
			// 			//liste archive
			// 			$where[] = array('table'=>'reservations','champ'=>'idNouvelleResa','valeur'=>'NOTNULL');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 8){
			// 			//liste pre affectation
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'9');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 9){
			// 			//liste desistement en cours
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'13');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 10){
			// 			//liste demande en attente
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'11');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 11){
			// 			//liste des refus
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'4,12','predicat'=>'IN');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 12){
			// 			//liste affectations
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'2');
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 13){
			// 			//liste des parti, sans changement de logement
			// 			$where[] = array('table'=>'reservations','champ'=>'etat','valeur'=>'6');
			// 			$where[] = array('table'=>'reservations','champ'=>'idNouvelleResa','valeur'=>"NULL");
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0');
			// 		}

			// 		if(!empty($liste['idType']) && $liste['idType'] == 14){
			// 			// récuperation de tous les archivés et actifs archie=0 et archive=1
			// 			$where[] = array('table'=>'reservations','champ'=>'archive','valeur'=>'0,1','predicat'=>'IN');
			// 		}

			// 		if($searchName){
			// 			//liste avec searchName explicite
			// 			$where[] = array('table'=>'locataires','champ'=>'nom','valeur'=>$searchName);
			// 		}



			// 		if($isResa){
			// 			//if(!$sessListe->rows){
			// 				// $rows = $this->getResaTable()->getListe(null,"FR",array('tables'=>$tablesSql,'where'=>$where,'idTypeListe'=>$liste['idType'],'limitStrat'=>0,'limitLength'=>$limit));
			// 				$tmpIdType = (array_key_exists('idType',$liste)?$liste['idType']:'');
			// 				$rows = $this->getResaTable()->getListe(null,"FR",array('tables'=>$tablesSql,'where'=>$where,'idTypeListe'=>$tmpIdType,'bredea'=>$conf->bredea));

			// 				$sessListe->rows = $rows;
			// 			//}else{
			// 				//$rows = $sessListe->rows;
			// 			//}
			// 		}else{
			// 			$rows = $this->getLocatairesTable()->getListe();
			// 		}

			// 		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			// 		//$rowsFinal = $resaRows;
			// 		$rowsFinal = array();


			// 		//$allInfosBredea = array();
			// 		$allInfosBredea = $this->readAllBredeaInfos();//demandes, resas et dossiers

			// 		if($ilYaDesChampsDynamiques){
			// 			$dynamiqueFieldsValue = $this->getLocatairesTable()->getAllInfosDynamiqueForLocs($adapter);
			// 		}

			// 		## on recupere les prochaine resa avec logement pour calculer le risque
			// 		$nexResas = $this->getResaTable()->getNextResas();
			// 		$totalDureeIC = $this->getTotalDureesIC();//le total des duree configuree des etapes
			// 		// pour calculer le risque on fait, totalDuree + ecart et le resultat on l ajoute au date depart
			// 		// puis on calccule la periode entre date fin previsionnelle et le prochain arrivee

			// 		## tableau des etat collectives validees
			// 		$icCollectiveArray = $this->getEtatICCollective();

			// 		if($isResa){
			// 			foreach ($rows as $row) {

			// 				// NEXT IC
			// 				$row->nextIC = $this->getNextEtatIC($row->idIntercontrat);



			// 				## intercontrat
			// 				if($row->etat==6 && $this->enIntercontrat($row) && !empty($liste['idType']) && $liste['idType'] == 2 ){
			// 					$etatEnCours = $this->getEtatIntercontratTable()->select(array('id'=>$row->idIntercontrat))->current();
			// 					$etatICResult = $this->getIntercontratTable()->select(array('idReservation'=>$row->id));

			// 					/* ADDED BY WADIE TO AVOID PARTI */
			// 					$row->etatIntercontrat = $etatEnCours->nom;
			// 					/* ADDED BY WADIE TO AVOID PARTI */
			// 					$ecart = 0;
			// 					foreach($etatICResult as $etatIC) {

			// 						if($row->idIntercontrat == $etatIC->idEtat){

			// 							// if ($etatIC->idReservation == '832') {
			// 							// 	var_dump($row);
			// 							// 	var_dump($etatIC);die();
			// 							// }

			// 							$decalage = $dureeReel = 0;
			// 							if($etatIC && $etatIC->dateEtat){
			// 								$dateDebut = new \DateTime(date('Y-m-d'));
			// 								$dateFin = new \DateTime($etatIC->dateEtat);
			// 								$difference = $dateDebut->diff($dateFin);

			// 								// if ($etatIC->idReservation == '832') {
			// 								// 	var_dump($dateDebut);
			// 								// 	var_dump($dateFin);
			// 								// 	var_dump($difference);
			// 								// 	die();
			// 								// }

			// 								$dureeReel = $difference->format('%a');

			// 								$dureeConfig = $this->getDuree($row->id, $row->idIntercontrat);
			// 								$decalage = $dureeReel - $dureeConfig;
			// 							}

			// 							$texte = "";
			// 							if($decalage > 0){
			// 								// $texte .= "<i class='fa fa-exclamation-triangle yellow'></i>$dureeReel j ";
			// 								$texte .= "<i class='fa fa-exclamation-triangle yellow'></i>$decalage j ";
			// 								$ecart += $decalage;
			// 							}
			// 							$texte .= $etatEnCours->nom;
			// 							$row->etatIntercontrat = $texte;
			// 						}else{
			// 							$ecart += abs($etatIC->decalage);
			// 						}
			// 					}
			// 					$row->ecart = $ecart;
			// 					## calcule risque
			// 					$dureeRestante = $totalDureeIC + $ecart;
			// 					if($dureeRestante > 0){
			// 						$dateFin = date('Y-m-d',strtotime($row->dateDepart." + $dureeRestante day"));
			// 					}else{
			// 						$dateFin = date('Y-m-d',strtotime($row->dateDepart." - $dureeRestante day"));
			// 					}
			// 					//on cherche la prochaine resa
			// 					$nextResa = !empty($nexResas[$row->idLogement]) ? $nexResas[$row->idLogement] : null;
			// 					//on clacule la difference entre la date fin et la nouvelle resa
			// 					if($nextResa){
			// 						$debut = new \DateTime($dateFin);
			// 						$fin = new \DateTime($nextResa->dateArrivee);
			// 						$difference = $debut->diff($fin);
			// 						$row->risque = $difference->format('%a');
			// 						//si la date debut > date fin , le risque sera negatif
			// 						if(strtotime($dateFin) > strtotime($nextResa->dateArrivee)){
			// 							$row->risque = $row->risque * (-1);
			// 						}
			// 					}else{
			// 						$row->risque = 999;//pas de nouvelle resa prevue
			// 					}

			// 					## collective
			// 					if(array_key_exists($row->idBatiment,$icCollectiveArray)){

			// 						$icCollLog = $icCollectiveArray[$row->idBatiment];
			// 						foreach($icCollLog as $cl){
			// 							$cl->idTheme = 2;
			// 							$cl->code = $cl->numero;
			// 							$cl->champ = $cl->nom;
			// 							$champs[$cl->idLogement] = $cl;
			// 							$ids[$cl->idLogement] = $cl->numero;
			// 							$ids1[$cl->idLogement] = $cl->numero;
			// 							$num = $cl->numero;

			// 							$row->$num = $cl->title;
			// 						}
			// 					}
			// 					## fin collective


			// 				}

			// 				if($isPlanning =='1' && $liste['idType'] == 1 && $row->etat != 1){
			// 					continue;
			// 				}
			// 				if($liste['idType'] == 1 && $row->etat != 1 && $row->etat != 10){
			// 					continue;
			// 				}

			// 				$extraLoc = array();
			// 				$idLocataire = $row->idLocataire;
			// 				if($ilYaDesChampsDynamiques){
			// 					//$extraLoc = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($idLocataire, $adapter);
			// 					//$extraLoc = $dynamiqueFieldsValue[$idLocataire];
			// 					$extraLoc = array_key_exists($row->id, $dynamiqueFieldsValue) ? $dynamiqueFieldsValue[$row->id] : NULL;
			// 				}

			// 				$resaArray = get_object_vars($row);
			// 				if(!empty($extraLoc)){
			// 					$all = array_merge($extraLoc,$resaArray);
			// 				}else{
			// 					$all = $resaArray;
			// 				}


			// 				##BREDEA
			// 				$site = $row->codeSite;
			// 				if($site && true){

			// 					if($row->numDossier){
			// 						$numero = $row->numDossier;
			// 						$allBredeaRows = !empty($allInfosBredea['dossiers']) ? $allInfosBredea['dossiers'] : array();
			// 					}elseif($row->numResa){
			// 						$numero = $row->numResa;
			// 						$allBredeaRows = !empty($allInfosBredea['resas']) ? $allInfosBredea['resas'] : array();
			// 					}elseif($row->idPMS){
			// 						$numero = $row->idPMS;
			// 						$allBredeaRows = !empty($allInfosBredea['demandes']) ? $allInfosBredea['demandes'] : array();
			// 					}
			// 					$numero = (int) $numero;
			// 					$customKey = $numero.'_'.$site;

			// 					$rowBredea = array_key_exists($customKey,$allBredeaRows ) ? $allBredeaRows[$customKey] : array();

			// 					if(!empty($rowBredea)){
			// 						//print_r($rowBredea);exit();
			// 						foreach($rowBredea as $champ=>$val){
			// 							if(trim($val)!="" && $champ!="civilite"){
			// 								$all[$champ] = utf8_encode($val);
			// 								if(array_key_exists($champ.'Locataire', $all)){
			// 									$all[$champ.'Locataire'] = utf8_encode($val);
			// 								}
			// 							}
			// 						}
			// 					}
			// 				}

			// 				//on verifie si changement de logement (meme dossier) :
			// 				//on affiche pas la date depart bredea pour l ancienne resa
			// 				//on affiche pas la date arrivee bredea pour la nouvelle resa

			// 				if($row->idNouvelleResa){
			// 					//on cherche la nouvelle resa pour verifie si les deux resa on le meme dossier
			// 					$nr = $this->getResaTable()->getResa($row->idNouvelleResa);
			// 					if($nr && $nr->numDossier == $row->numDossier){
			// 						$all['dateDepart'] = $row->dateDepart;
			// 					}elseif($nr && $nr->etat == 15){
			// 						//si la resa est en cours de changement
			// 						$all['etatReservation'] .= " - en cours de changement ".$nr->numeroChambre."";
			// 						$all['dateDepart'] = $row->dateDepart;
			// 					}
			// 				}
			// 				if($row->idAncienneResa){
			// 					//on cherche l ancienne resa pour verifie si les deux resa on le meme dossier
			// 					$nr = $this->getResaTable()->getResa($row->idAncienneResa);
			// 					if($nr && $nr->numDossier == $row->numDossier){
			// 						$all['dateArrivee'] = $row->dateArrivee;
			// 					}
			// 				}
			// 				if($row->idCampagne == 3){
			// 					//print_r($all);echo "<br><br>";
			// 				}


			// 				$rowsFinal[] = $all;
			// 				unset($row);
			// 				unset($resaArray);
			// 				unset($all);
			// 				unset($rowBredea);
			// 				unset($extraLoc);
			// 			}
			// 		}
			// 	}
			// 	//exit();
			// 	$tmpIdType = (array_key_exists('idType',$liste)?$liste['idType']:'');

			// 	$intercontrats = $this->getRealEtatintercontratTable()->fetchAll();

			// 	$ColReorder	= $sessListe->ColReorder;
			// 	$htmlViewPart = new ViewModel();
			// 	$htmlViewPart->setTerminal(true)
			// 	->setTemplate('reservation/liste/afficher')
			// 	->setVariables(array(
			// 			'rows' => $rowsFinal,
			// 			'themes' => $champs,
			// 			'isResa' => $isResa,
			// 			'idListe'=>$idListe,
			// 			'idTypeListe'=>$tmpIdType,
			// 			'data'=>$data,
			// 			'dateFilter'=>$dateFilter,
			// 			'numberFilter'=>$numberFilter,
			// 			'optionPerdue'=>$optionPerdue,
			// 			'dureeRelance'=>$dureeRelance,
			// 			'choixTable'=>$this->getChoixTable(),
			// 			'resaTable'=>$this->getResaTable(),
			// 			'limit'=>$limit,
			// 			'isPlanning'=>$isPlanning,
			// 			'idCss'=>$idCss,
			// 			'intercontrats' => $intercontrats,
			// 			'ColReorder'=>$ColReorder,
			// 			'conf'=>$conf,
			// 	));


			// 	$htmlOutput = $this->getServiceLocator()
			// 		->get('viewrenderer')
			// 		->render($htmlViewPart);


			// 	$view = new JsonModel(array(
			// 		'success'=>true,
			// 		'champs'=>$ids,
			// 		'liste' => $liste,
			// 		'htmlOP'=>$htmlOutput,
			// 		'data'=>$data,
			// 	));


			// 	$view->setTerminal(true);
			// 	return($view);
			// }
		}
	}

	//charger les lignes demandées en mode serverSide
	public function getServerJsonDataAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest() || $request->getPost()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$typeAppel = $request->getPost('typeAppel');//si on appel l'action depuis le controlleur ou la vue
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');
			$idListe	= $request->getPost('idListe');
			$isPlanning	= $request->getPost('isPlanning');
			$searchName = $request->getPost('searchName', '');
			$searchPrenom = $request->getPost('searchPrenom', '');
			$searchCodeLocataire = $request->getPost('searchCodeLocataire', '');
			$searchNumeroChambre = $request->getPost('searchNumeroChambre', '');
			$searchArchive = $request->getPost('searchArchive', '');
			$rechercheStricteNom = $request->getPost('rechercheStricteNom', '');
			$rechercheStrictePrenom = $request->getPost('rechercheStrictePrenom', '');
			$rechercheStricteDateNaissance = $request->getPost('rechercheStricteDateNaissance', '');
			$rechercheStricteArchive = $request->getPost('rechercheStricteArchive', '');

			$startDate = $request->getPost('startDate', '');
			$endDate = $request->getPost('endDate', '');

			$fetchMode 	= $request->getPost('fetchMode', '');

			$modeEditionInline 	= $request->getPost('modeEditionInline', '');
			$degroupe = $request->getPost('degroupe', '');

			if($fetchMode == 'rowChilds') {
				foreach ($columns as $key => $column) {
					$columns[$key]['name'] = $column['data'];
				}
			}

			if ($startDate) {
				$startDate = date('Y-m-d', strtotime($startDate));
				$endDate = date('Y-m-d', strtotime($request->getPost('endDate') ? $request->getPost('endDate') : '01-01-2038'));
			}

			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

			## filtre bandeau
			$sessFB = new Container('filtreBandeau');
			$FiltresBandeau = isset($sessFB->filtres) ? $sessFB->filtres : array();

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : post=".json_encode($request->getPost()));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : draw=$draw start=$start length=$length idListe=$idListe");
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : columns=".json_encode($columns));
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : order=".json_encode($order));

			## Lecture du type de liste
			## ~~~~~~~~~~~~~~~~~~~~~~~~
			$listeDescr = $this->getListesTable()->getListe($idListe);
			if ($listeDescr) {
				$typeListe	= $listeDescr->idType;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe");

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('draw'	=> 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0, 'columns' => $columns);

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonResaDatatableState		= $this->loadResaState($idListe);
			$jsonResaDatatableFilter	= $jsonResaDatatableState ? $jsonResaDatatableState['filter'] : [];

			if (is_array($jsonResaDatatableFilter) && $columns) {

				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getResaFields($idListe, $jsonResaDatatableFilter);
			}


			## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$listeChampsAffiches	= array(
				'idLocataire' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
				'idReservation' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
				'idGroupeResa' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idGroupeResa', 'visible' => false),

				'dateArrivee' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateArrivee', 'visible' => false),

				'dateArriveeTheorique' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateArriveeTheorique', 'visible' => false),

				'dateDepart' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateDepart', 'visible' => false),

				'dateDepartTheorique' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateDepartTheorique', 'visible' => false),
			);


			// var_dump($listeChampsAffiches);die();
			foreach ($columns as $_key => $_column) {
				$_colName	= $_column[data];
				// if (0) {
				// 	if ($_colName) {
				// 		## Recherche du champ dans les différentes listes de champs
				// 		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// 		foreach ($formFields as $_typeField => $_fields) {
				// 			if (($_field = $_fields[$_colName])) {
				// 				if ($_typeField == 'dynFields') {
				// 					if (array_key_exists($_colName, $listeChampsAffiches)) {
				// 						## Juste un ajout d'un autre champ ID
				// 						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// 						$listeChampsAffiches[$_colName]['idChamp'][]	= $_field->idChamp;
				// 					} else {
				// 						$listeChampsAffiches[$_colName] = array(	'dyn'=>1,
				// 												'typeField'=>$_typeField,
				// 												'idTypeHtml'=>$_field->idTypeHtml,
				// 												'table'=>$_field->table,
				// 												'idChamp'=>array($_field->idChamp),
				// 												'equivalentSql'=>$_field->equivalentSql,
				// 												'sourceListe' =>$_field->sourceListe);
				// 					}
				// 				} else {
				// 					$listeChampsAffiches[$_colName] = array(	'dyn'=>0,
				// 											'typeField'=>$_typeField,
				// 											'idTypeHtml'=>$_field->idTypeHtml,
				// 											'table'=>$_field->table,
				// 											'idChamp'=>$_field->id,
				// 											'equivalentSql'=>$_field->equivalentSql,
				// 											'sourceListe' =>$_field->sourceListe);
				// 				}
				// 				break;
				// 			}
				// 		}
				// 		if (!$listeChampsAffiches[$_colName]) {
				// 			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : _colName=$_colName absent dans fields");
				// 		}
				// 	}
				// }
				// else {
				// print_r($formFields);die();
				if ($_colName && !array_key_exists($_colName, $listeChampsAffiches) && count($formFields) > 0) {
					## Recherche du champ dans les différentes listes de champs
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					foreach ($formFields as $_typeField => $_fields) {
						if ($_typeField == "activeFields") {
							continue;
						}

						if (($_field = $_fields[$_colName])) {
							if ($_typeField == 'dynFields') {
								$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
														'typeField' => $_typeField,
														'idTypeHtml' => $_field->idTypeHtml,
														'table' => $_field->table,
														'idChamp' => $_field->idChamp,
														'equivalentSql' => $_field->equivalentSql,
														'sourceListe' => $_field->sourceListe,
														'visible' => true);
								if (($_field->table == "champs_suivis" || $_field->table == "suivis") && $_field->idTypeSuivis) {
									$listeChampsAffiches[$_colName]['idTypeSuivis'] = $_field->idTypeSuivis;
								} elseif ($_field->table == "champs_catalogue" && $_field->idTypeCatalogue) {
									$listeChampsAffiches[$_colName]['idTypeCatalogue'] = $_field->idTypeCatalogue;
								}
							} else {
								$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
														'typeField' => $_typeField,
														'idTypeHtml' => $_field->idTypeHtml,
														'table' => $_field->table,
														'idChamp' => $_field->id,
														'equivalentSql' => $_field->equivalentSql,
														'sourceListe' => $_field->sourceListe,
														'visible' => true);

								if (($_field->table == "suivis") && $_field->idTypeSuivis) {
									$listeChampsAffiches[$_colName]['idTypeSuivis'] = $_field->idTypeSuivis;
								}
							}
							break;
						}
					}
					if (!$listeChampsAffiches[$_colName]) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : _colName=$_colName absent dans fields");
					}
				}
				// }
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe nb_listeChampsAffiches=".count($listeChampsAffiches));
			}

			## Version nouvelle de lecture de la BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$where	= ($isPlanning && $typeListe == 1) ? array("reservations.etat" => 1) : array();

			$residences = [];
			$gestionnaire_residences = $this->getTableObjet('gestionnaire_residences')->select(array('idGestionnaire' => $gestId));
			foreach ($gestionnaire_residences as $row) {
				$residences[] = $row->idResidence;
			}
			if ($residences && !$rechercheStricteNom) {
				## Dans le cas des recherches strictes, pas de contraintes de résidence ou campagne
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if(array_key_exists('typeLogement1', $listeChampsAffiches)) {
					$subQueryTL = "IF( (SELECT ct.idTypeLogement FROM choix_typelogement as ct WHERE reservations.id = ct.idReservation AND ct.numeroChoix = 1 LIMIT 1),(SELECT batiments.idResidence FROM choix_typelogement as ct2 LEFT JOIN typelogement_batiment ON ct2.idTypeLogement = typelogement_batiment.idTypeLogement LEFT JOIN batiments ON typelogement_batiment.idBatiment = batiments.id WHERE reservations.id = ct2.idReservation AND ct2.numeroChoix = 1 LIMIT 1) IN (".implode(',', $residences).") , 1=1)";
					$subQueryR = "IF( (SELECT ct.idResidence FROM choix_typelogement as ct WHERE reservations.id = ct.idReservation AND ct.numeroChoix = 1 LIMIT 1),(SELECT ct2.idResidence FROM choix_typelogement as ct2 WHERE reservations.id = ct2.idReservation AND ct2.numeroChoix = 1 LIMIT 1) IN (".implode(',', $residences).") , $subQueryTL)";
				} else {
					$subQueryR = "1=1";
				}

				$subQuery1 = "IF(reservations.residenceOrientation > 0,reservations.residenceOrientation IN (".implode(',', $residences)."),$subQueryR )";
				//array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',',$residences)."),1=1 )");
				array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',', $residences)."),$subQuery1 )");
			}

			$campagnesDeGest = [];
			## on vérifie si on a le droit d'attribution campagne, si oui on controle les campagnes sinon on affiche tout
			if($_SESSION['USERDROIT']['user-campagnes'] == 'W'){
				$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
				foreach ($gestionnaire_campagnes as $row) {
					$campagnesDeGest[] = $row->idCampagne;
				}
			}
			if (!empty($campagnesDeGest) && !$rechercheStricteNom) {
				array_push($where, "IF(reservations.idCampagne > 0,reservations.idCampagne IN (".implode(',', $campagnesDeGest)."),1=1 )");
			}

			if ($searchNumeroChambre != "") {
				array_push($where, "reservations.numeroChambre LIKE '".$searchNumeroChambre."%'");
			}
			if ($searchArchive == "1") {
				array_push($where, "reservations.archive IN ('0','1')");
			}

			if ($searchName != "") {
				array_push($where, "locataires.nom LIKE '".$searchName."%'");
			}

			if ($searchPrenom != "") {
				array_push($where, "locataires.prenom LIKE '".$searchPrenom."%'");
			}
			if ($rechercheStricteNom != "") {
				array_push($where, "locataires.nom = '".$rechercheStricteNom."'");
			}
			if ($rechercheStrictePrenom != "") {
				array_push($where, "locataires.prenom = '".$rechercheStrictePrenom."'");
			}
			if ($rechercheStricteDateNaissance != "") {
				array_push($where, "locataires.dateNaissance = '".$rechercheStricteDateNaissance."'");
			}
			if ($rechercheStricteArchive == '1') {
				array_push($where, "reservations.archive IN ('0','1')");
			}

			if ($searchCodeLocataire != "") {
				array_push($where, "locataires.codeLocataire LIKE '".$searchCodeLocataire."%'");
			}

			## filtresBandeau
			if (!empty($FiltresBandeau)) { // mode reservation


				if (!empty($FiltresBandeau['idResidence'])) {
					$in = implode(',', $FiltresBandeau['idResidence']);
					//array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".$in."),1=1 )");
					array_push($where, "batiments.idResidence IN (".$in.")");
				}
				if (!empty($FiltresBandeau['idBatiment'])) {
					$in = implode(',', $FiltresBandeau['idBatiment']);
					//array_push($where, "IF(reservations.idLogement > 0,batiments.id IN (".$in."),1=1 )");
					array_push($where, "batiments.id IN (".$in.")");
				}
				if (!empty($FiltresBandeau['idCampagne'])) {
					$in = implode(',', $FiltresBandeau['idCampagne']);
					array_push($where, "reservations.idCampagne IN ($in)");
				}
				if (!empty($FiltresBandeau['idProgramme'])) {
					$in = implode(',', $FiltresBandeau['idProgramme']);
					array_push($where, "reservations.idProgramme IN ($in)");
				}
				if (!empty($FiltresBandeau['idSousProgramme'])) {
					$in = implode(',', $FiltresBandeau['idSousProgramme']);
					array_push($where, "reservations.idSousProgramme IN ($in)");
				}
			}

			## dates de filtre sur les presents
			if ($startDate && $endDate) {
				array_push($where, 'IF(reservations.dateDepart AND reservations.dateDepart!=\'0000-00-00\',reservations.dateDepart >= "'.$startDate.'" AND reservations.dateArrivee <= "'.$endDate.'", reservations.dateArrivee <= "'.$endDate.'")');
			}

			if ($fetchMode == "oneRow") {
				$idPrestaResa =  $request->getPost('idPrestaResa', 0);
				if ($idPrestaResa > 0) {
					array_push($where, "prestations_to_resa.id = $idPrestaResa");
				}
				$idReservation =  $request->getPost('idReservation', 0);
				if ($idReservation > 0) {
					array_push($where, "reservations.id = $idReservation");
				} else {
					$fetchMode = "";
				}
			}

			if($fetchMode == "rowChilds") {
				$idReservation = $request->getPost('idReservation', 0);
				$idMenageResa = $request->getPost('idMenageResa', 0);
				$idResidenceOrientationMenage = $request->getPost('idResidenceOrientation', 0);
				$idResidenceMenage = $request->getPost('idResidence', 0);
				$multipleDossiers = $request->getPost('multipleDossiers', 0);//cas des famille avec multiples dossier sur le meme dispositif
				$idEtatReservation = $request->getPost('idEtatReservation', 0);
				$dateDepartReservation = $request->getPost('dateDepartReservation', '');
				if($idReservation && $idMenageResa) {
					$whereStr = "(reservations.idMenage = $idMenageResa AND reservations.id != $idReservation";
					if($idResidenceOrientationMenage > 0) {
						$whereStr .= " AND reservations.residenceOrientation = $idResidenceOrientationMenage";
					} elseif($idResidenceMenage > 0) {
						$whereStr .= " AND residences.id = $idResidenceMenage";
					}
					if($multipleDossiers == '1') {
						if($dateDepartReservation) {
							$whereStr .= " AND reservations.dateDepart = '$dateDepartReservation'";
						} else {
							$whereStr .= " AND (reservations.dateDepart = '' OR reservations.dateDepart IS NULL )";
						}
					}
					$whereStr .= ")";
					array_push($where, $whereStr);
				}
			}

			// print_r($listeChampsAffiches);die();
			if ($typeListe == 24) {
				//liste qui groupes toutes les listes de type indicateurs
				$rowsAll = $this->getAllListesIndicateursRows();
			} else {
				$rowsAll = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where, array('config' => $conf, 'fetchMode' => $fetchMode, 'degroupe' => $degroupe));
				if($typeListe == 18) {
					//pour la liste des prestation calculé, on a besoin de une ligne de present + une ligne prestations_to_resa si existe
					$rowsAll_2 = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where, array('config' => $conf, 'fetchMode' => $fetchMode, 'cible' => 'presents'));
					$rowsAll = array_merge($rowsAll, $rowsAll_2);
				}
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsAll=".count($rowsAll)." debut_rowsAll=".json_encode(array_slice($rowsAll, 0, 1)));

			## Traitement de la partie "server side"
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$output['recordsTotal']		= count($rowsAll);
			//print_r($rowsAll);exit();
			if ($rowsAll) {
				## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				## Construire une liste des champs avec dates
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$colDates	= array();
				$colRadios = array();
				$colNombres = array();
				$colCheckbox = array();
				$colsTypes = array();
				$selectVals = array();
				if ($listeChampsAffiches) {
					foreach ($listeChampsAffiches as $_colName => $_col) {
						if ($_col[idTypeHtml] == 2 /*|| $_col[idTypeHtml] == 19*/) {
							$colDates[]	= $_colName;
						} elseif ($_col[idTypeHtml] == 9) {
							$colRadios[]	= $_colName;
						} elseif ($_col[idTypeHtml] == 5 || $_col[idTypeHtml] == 12 || $_col[idTypeHtml] == 13) {
							$colNombres[]	= $_colName;
						} elseif ($_col[idTypeHtml] == 8) {
							$colCheckbox[]	= $_colName;
						} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
							$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
						}
						$colsTypes[$_colName] = $_col[idTypeHtml];
					}
				}

				## Vérification champ controleChampObligatoire pour voir si on a au moins un champ obligatoire non renseigné
				/*$champsObligatoireParCampagne = array();
				$controleChampObligatoire = false;
				$obligatoireVide = false;
				if(array_key_exists('controleChampObligatoire',$listeChampsAffiches)){
					$controleChampObligatoire = true;
					$tableChampsForms = $this->getTableObjet('champs_formulaires');
					$select = $tableChampsForms->getSql()->select();
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire'=>'id','idCampagne'));
					$select->where(array('champs_formulaires.obligatoire'=>'1','champs_formulaires.active'=>'1','formulaires.active'=>'1'));
					$champsResult = $tableChampsForms->selectWith($select);
					foreach ($champsResult as $ch) {
						$champsObligatoireParCampagne[$ch->idCampagne][$ch->equivalentSql] = $ch->id;
					}
				}*/

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

				## recup des bonne valeurs des champs de type radio selon la campagne
				$radioOptions = array();
				if (!empty($colRadios)) {
					$tableChampsForms = $this->getTableObjet('champs_formulaires');
					$select = $tableChampsForms->getSql()->select();
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
					$select->where->in('equivalentSql', $colRadios);
					$champs = $tableChampsForms->selectWith($select);
					foreach ($champs as $ch) {
						$options = explode(";", $ch->options);
						$radioOptions[$ch->idCampagne][$ch->equivalentSql] = $options;
					}
				}

				if ($colDates || !empty($radioOptions) || !empty($selectVals)) {
					$rowsAll1	= array();
					foreach ($rowsAll as $key => $row) {
						if ($colDates) {
							foreach ($colDates as $_colName) {
								$rowValue	= $row[$_colName];
								if ($rowValue && strpos($rowValue, '-') == 2) {
									## Date au format dd-mm-yyyy -> il faut convertir
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									list($dd, $mm, $yyyy)	= explode("-", $rowValue);
									$row[$_colName]		= "$yyyy-$mm-$dd";
								}
							}
						}
						## remplacer les valeurs radio avec les bonne valeurs
						if (!empty($radioOptions)) {
							foreach ($colRadios as $_colName) {
								if (in_array($_colName, $colRadios)) {
									if (!empty($radioOptions[$row['idCampagne']][$_colName][$row[$_colName]])) {
										$row[$_colName] = $radioOptions[$row['idCampagne']][$_colName][$row[$_colName]];
									} else {
										$row[$_colName] = "";
									}
								}
							}
						}
						##Select multiple
						if(!empty($selectVals)) {
							foreach($selectVals as $_colName => $sVals) {
								$rowValue	= $row[$_colName];
								if($rowValue) {
									$rowValueArr = explode(',', $rowValue);
									if(!empty($rowValueArr)) {
										$rowValueNew = '';
										foreach($rowValueArr as $v) {
											$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
											$rowValueNew .= ', ';
										}
										$rowValueNew = substr($rowValueNew, 0, -2);
										if($rowValueNew) {
											$row[$_colName]	= $rowValueNew;
										}
									}
								}
							}
						}
						## Listes type famille, pour remettre le numero de logement du dossier parent pour les sous dossiers
						if($typeListe == 23 && $fetchMode == 'rowChilds') {
							if(array_key_exists('numeroChambre', $row) && empty($row['numeroChambre']) && !empty($row['numeroChambreParent'])) {
								$row['numeroChambre'] = $row['numeroChambreParent'];
							}
							if(array_key_exists('numeroLogement', $row) && empty($row['numeroLogement']) && !empty($row['numeroChambreParent'])) {
								$row['numeroLogement'] = $row['numeroChambreParent'];
							}
							if(array_key_exists('logements_nom', $row) && empty($row['logements_nom']) && !empty($row['numeroChambreParent'])) {
								$row['logements_nom'] = $row['numeroChambreParent'];
							}
							if(array_key_exists('adrLogementComple', $row) && empty($row['adrLogementComple']) && !empty($row['adrLogementCompleParent'])) {
								$row['adrLogementComple'] = $row['adrLogementCompleParent'];
							}
						}

						## controle champs obligatoires
						//if($controleChampObligatoire && !empty($champsObligatoireParCampagne)){
						//$row['controleChampObligatoire'] = '';
						//}

						$rowsAll1[]	= $row;
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
					$rowsAll	= $rowsAll1;
				}


				## Constitution d'une liste de types de filtres
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$searchTypes	= array();
				foreach ($jsonResaDatatableFilter as $fieldName => $field) {
					$searchTypes[$fieldName]	= $field['type'];
					if (in_array($fieldName, $colRadios)) {
						$searchTypes[$fieldName]	= "text";
					}//traiter les champs radio comme des text
					if (in_array($fieldName, $colCheckbox)) {
						$searchTypes[$fieldName]	= "checkbox";
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));


				## Filtrage dans la table
				## ~~~~~~~~~~~~~~~~~~~~~~
				$searchs	= array();
				foreach ($columns as $key => $column) {
					## Constitution d'une liste de filtres dans la requete Ajax
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colName	= $column[name];
					$value		= $column[search][value];
					//si value == 'null' cad filtre sur valeur vide pour les select
					// si == " " filtre sur valeur vide champs texte
					if ($colName && $column[searchable] && ($value || $value == 'null' || $value == " ")) {
						$searchType	= $searchTypes[$colName];
						if ($colName == 'Action') {
							$searchType = 'select';
							$column[data] = 'nouvelEtat';
						}
						if ($value == 'null' || $value == " ") {
							$value = null;
						}
						if ($searchType == 'date' || $searchType == 'number' && $value) {
							## Toutes les dates sont au format YYYY-MM-DD, donc triables
							list($min, $max, $vide)		= explode("|", $value);
							$searchs[$colName][colInd]	= $column[data];
							$searchs[$colName][type]	= $searchType;
							$searchs[$colName][min]		= $min;
							$searchs[$colName][max]		= $max;
							$searchs[$colName][vide]		= $vide;
						} elseif ($searchType == 'text' || $searchType == 'checkbox') {
							$searchs[$colName][colInd]	= $column[data];
							$searchs[$colName][type]	= $searchType;
							$searchs[$colName][text]	= $value;
						} elseif ($searchType == 'select') {
							$searchs[$colName][colInd]	= $column[data];
							$searchs[$colName][type]	= $searchType;
							$explode = explode("|", $value);
							$selectOpt = array();
							foreach ($explode as $sVal) {
								if ($sVal == 'null' || $sVal == " ") {
									$sVal = null;
								}
								$selectOpt[] = $sVal;
							}
							if ($colName == 'Action') {
								$searchs[$colName][values] = $value;
							} else {
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

				$rowsSel	= array();
				if ($searchs || $searchGlobalVal != "") {
					$searchGlobalValSTR = $searchGlobalVal;
					## Parcourir les sorties pour filtrer à la main
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					foreach ($rowsAll as $key => $row) {
						foreach ($searchs as $colName => $search) {
							$rowValue	= $row[$search['colInd']];
							if($colName == 'dureeSejour') {
								$rowValue = trim(str_replace('jours', '', $rowValue));
								$rowValue = trim(str_replace('mois', '', $rowValue));
							}
							if ($search['type'] == 'date') {
								$rowValue = date('Y-m-d', strtotime($rowValue));

								if ($search['vide'] == '1') {
									$condVide = (trim($row[$search['colInd']]) != '' && substr($row[$search['colInd']], 0, 2) != "00");
									if ($search[min] != '') {
										if ($condVide && $rowValue < $search[min]) {
											continue 2;
										}
										if ($search[max] != '') {
											if ($condVide && $rowValue > $search[max]) {
												continue 2;
											}
										}
									} else {
										if ($search[max] != '') {
											if ($condVide && $rowValue > $search[max]) {
												continue 2;
											}
										} else {
											if ($condVide) {
												continue 2;
											}
										}
									}
								} else {
									//on ne prend pas en compte les dates vides:
									$condVide = (trim($row[$search['colInd']]) == '' || substr($row[$search['colInd']], 0, 2) == "00");
									if (($search[min] != '' || $search[max] != '') && $condVide) {
										continue 2;
									}
									if (($search[min] != '') && $rowValue < $search[min]) {
										continue 2;
									}
									if (($search[max] != '') && $rowValue > $search[max]) {
										continue 2;
									}
								}
							} elseif ($search['type'] == 'number') {
								if ($search[min] != ''  && $rowValue < $search[min]) {
									continue 2;
								}
								if ($search[max] != '' && $rowValue > $search[max]) {
									continue 2;
								}
							} elseif ($search['type'] == 'text') {
								if ($conf->filtreAverEtoile == 1) {
									//prise en compte de mode de recherche avec etoile
									$contain = false;
									$startWith = false;
									$finishWith = false;

									if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
										//contient un etoile
										$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
										$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($search['text'], 0, 1) == '*') {
										//commence avec etoile
										$search['text'] = substr($search['text'], 1, strlen($search['text']));
										$finishWith = true;
									} elseif (substr($search['text'], -1, 1) == '*') {
										//fini par un etoile
										$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}


									if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
									if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
										continue 2;
									}

									if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
										continue 2;
									}
								} else {
									if (stripos(strtolower(utf8_decode($rowValue)), strtolower(utf8_decode($search['text']))) === false && $search['text'] != null) {
										continue 2;
									}
								}
								if ($search['text'] == null && $rowValue) {
									continue 2;
								}
								//prise en compte des valeurs null si on filtre sur null
							} elseif ($search['type'] == 'select') {
								## Filtre sur colonne Action, liste changement logement
								if ($colName == 'Action') {
									if ($search['values'] == 'Changed' && $rowValue == 15) {
										continue 2;
									} elseif ($search['values'] == 'En attente' && $rowValue != 15) {
										continue 2;
									}
								} else {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
								}
								//prise en compte des valeurs null si on filtre sur null
							} elseif ($search['type'] == 'checkbox') {
								$rowValue = $rowValue ? 'oui' : 'non';
								if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
									continue 2;
								}
							}
						}
						## Recherche global
						if ($searchGlobalVal != "") {
							$trouve = false;
							$contain = false;
							$startWith = false;
							$finishWith = false;

							if ($conf->filtreAverEtoile == 1) {
								if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
									//contient un etoile
									$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
									$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
									$contain = true;
								} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
									//commence avec etoile
									$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
									$finishWith = true;
								} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
									//fini par un etoile
									$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
									$startWith = true;
								} else {
									$startWith = true;
								}
							}

							foreach ($columns as $key => $column) {
								$rowValue	= $row[$column['name']];
								if ($conf->filtreAverEtoile == 1) {
									//prise en compte de mode de recherche avec etoile

									if ($contain) {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									} elseif ($finishWith) {
										if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
											$trouve = true;
										}
									} elseif ($startWith) {
										if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
											$trouve = true;
										}
									}
								} else {
									if (stripos($rowValue, $searchGlobalVal) !== false) {
										$trouve = true;
									}
									if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
										$trouve = true;
									}
								}
							}

							if (!$trouve) {
								continue;
							}
						}
						$rowsSel[]	= $row;
					}
				} else {
					$rowsSel	= $rowsAll;
				}

				## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$sortOrder	= array();
				if ($order) {
					foreach ($order as $_key => $_order) {
						if(!array_key_exists('column', $_order) && sizeof($_order) == 2) {
							$_order['column'] = $_order[0];
							$_order['dir'] = $_order[1];
						}
						$_colInd	= $_order['column'];
						$_colName	= $columns[$_colInd]['name'];
						if ($_colInd && $_colName) {
							$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
							$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

				## Tri de la table
				## ~~~~~~~~~~~~~~~
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSel=".count($rowsSel)." debut_rowsSel=".json_encode(array_slice($rowsSel, 0, 1)));


				if(!($typeListe == 23 && $fetchMode == 'rowChilds')) {
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				}

			} else {
				$rowsSel	= $rowsAll;
			}

			if ($modeEditionInline == "global") {
				$rowsSel2 = $rowsSel;
				$rowsSel = array();

				$champNonModifiable = $this->getAllChampsNonModifiable();

				foreach ($rowsSel2 as $row) {
					foreach ($row as $champName => $value) {
						if (in_array($champName, $champNonModifiable)) {
							continue;
						}

						$idType = !empty($colsTypes[$champName]) ? $colsTypes[$champName] : 0;
						if ($idType == 13) {
							continue;
						}//ne pas rendre editable les champs formules
						if ($idType == 2 && $value && $value != "0000-00-00") {
							$value = date('d-m-Y', strtotime($value));
						}

						$params = array('idResa' => $row['idReservation'],
									'isResa' => 1,
									'champCode' => $champName,
									'actualValue' => $value,
									'idDp' => 0,
									'mode' => 'reservation',
									'modeEditionInline' => $modeEditionInline,
									 );
						$return = $this->editChampInline($params);

						if (!empty($return['htmlOP']) && $return['htmlOP'] != "") {
							$row[$champName] = $return['htmlOP'];
						}
					}
					$rowsSel[] = $row;
				}
			}

			$output['recordsFiltered']	= count($rowsSel);
			$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSlice=".count($rowsSlice)." rows_rowsSlice=".json_encode(array_slice($rowsSlice, 0, 2)));
			// }

			/*if (count($rowsSlice) > 0) {
				$cpts	= array();
				// foreach ($rowsSlice as $key => $row) {
				for ($i=0; $i < count($rowsSlice); $i++) {
					$cpts[nbLignes]++;
					$keysArr = is_array($rowsSlice[$i]) ? array_keys($rowsSlice[$i]) : array();
					foreach ($keysArr as $key => $value) {
						$cpts[nbColonnes]++;
						$champAffiche	= $listeChampsAffiches[$value];
						if (strpos($value, 'libre_') !== false) {
							$cpts[nbLibres]++;
							//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe nameChamps=$value idTypeHtml=$champAffiche[idTypeHtml] sourceListe=$champAffiche[sourceListe]");
							if ($champAffiche[idTypeHtml] == 18) {
								$cpts[nbMultiselect]++;
								// on récupère les valeurs correpondantes dans demandes_values
								$valeurs_select = $this->getTableObjet('valeurs_select')
								->select(array('idSelect' => $champAffiche[sourceListe]))->toArray();

								$valuesMultiple = "";
								$idsOrigin = explode(",", $rowsSlice[$i][$value]);

								foreach ($valeurs_select as $key => $vs) {
									foreach ($idsOrigin as $key => $idsO) {
										if ($vs['id'] == $idsO) {
											$valuesMultiple .= $vs['valeur'] . ", ";
										}
									}
								}

								$valuesMultiple = substr($valuesMultiple, 0, -2);
								if ($valuesMultiple) {
									$rowsSlice[$i][$value] = $valuesMultiple;
								}

								// echo "<pre>";
								// print_r($valuesMultiple);
								// echo "</pre>";
								// die();
							}
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe cpts=".json_encode($cpts));
			}*/


			//pour afficher le total de lignes d'une listes dans le tableau de bord
			if ($request->getPost() && $typeAppel == "controller") {
				return $output;
			}

			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;
			if ($request->getPost() && $typeAppel == "modeIndicateurs") {
				return $output;
			}
			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function getResaFields($idListe = 0, $jsonResaDatatableFilter = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe");

		$configFilter = $this->getConfigFiltersTable()->getListeFilter($idListe, 'reservation');

		$champsTranslations = $this->getAllChampsTranslation();
		$resaFields = $dynFields = array();
		$activeFields = ['resaRow' => [], 'dynRow' => []];

		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		## Liste des champs fixes par thèmes
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$select1 = $tableObj->getTable()->getSql()->select();
		#$select1->where('idTheme = 1 OR idTheme = 2 OR idTheme = 3');
		$select1->where('idTheme IN (1,2,3,6,7,15)');
		$select1->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select1);

		$champsNonTraduite = array('residence', 'numeroChambre');

		$typesSuivis = array();
		$tsRows = $this->getTableObjet('type_suivi')->select();
		foreach ($tsRows as $ts) {
			$typesSuivis[$ts->id] = $ts;
		}

		if ($themeResult) {
			foreach ($themeResult as $row) {
				if ($row->idTheme == 2 && $row->table == 'suivis') {
					$champSquivalentSql = $row->equivalentSql;
					$champCode = $row->code;
					$champNom = $row->nom;
					foreach ($typesSuivis as $ts) {
						$rowN = clone $row;
						$code = $champCode."_TS_".$ts->id;
						$nom = $champNom . " (".$ts->type.")";
						$equivalentSql = $champSquivalentSql;//."_TS_".$ts->id;
						if ($jsonResaDatatableFilter) {
							$activeFields['dpRow'][$code] =
							$rowN->checked = array_key_exists($code, $jsonResaDatatableFilter);
						}
						$rowN->code = $code;
						$rowN->idTypeSuivis = $ts->id;
						$rowN->nom = $nom;
						$rowN->equivalentSql = $equivalentSql;
						if ($jsonResaDatatableFilter) {
							$activeFields['resaRow'][$code] =
							$rowN->checked = array_key_exists($code, $jsonResaDatatableFilter);
						}

						if ($equivalentSql && array_key_exists($equivalentSql, $champsTranslations) && !in_array($code, $champsNonTraduite) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
							$rowN->nom = $champsTranslations[$equivalentSql];
						}

						$rowN->hasDynFilter = (!empty($configFilter) && array_key_exists($equivalentSql, $configFilter)) ? '1' : '';
						$resaFields[$code] = $rowN;
					}
				} else {
					if ($jsonResaDatatableFilter) {
						$activeFields['resaRow'][$row->code] = $row;
						$row->checked = array_key_exists($row->code, $jsonResaDatatableFilter);
						//modif pour les champs de type ville ou villeLocataire pour que ça fonctionne pour les deux
						//if(!array_key_exists($row->code, $jsonResaDatatableFilter) && $row->table=="locataires"){
						//$row->checked = array_key_exists($row->equivalentSql, $jsonResaDatatableFilter);
						//}
					}

					if ($row->equivalentSql && array_key_exists($row->equivalentSql, $champsTranslations) && !in_array($row->code, $champsNonTraduite) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$row->nom = $champsTranslations[$row->equivalentSql];
					}

					if ($jsonResaDatatableFilter[$row->equivalentSql]['libelle'] && trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']) != '') {
						$row->nom = trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']);
					}

					$row->hasDynFilter = (!empty($configFilter) && array_key_exists($row->equivalentSql, $configFilter)) ? '1' : '';
					$resaFields[$row->code] = $row;
				}
			}
		}

		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique($full = true);
		if ($champsDynamiques) {
			foreach ($champsDynamiques as $row) {
				if($row->idChampSuivis > 0) {
					continue;
				}
				$_code	= $row->equivalentSql;
				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;

					$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($_code, $configFilter)) ? '1' : '';

					$dynFields[$_code] = $obj;
				} else {
					if($row->idType == 19) {
						$row->idType = $this->getGlobalHelper()->getTypeChampFormuleDate($row->id);
					}
					$obj = new \stdClass();
					$obj->table = 'champs_dynamiques';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['resaRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}
					if ($jsonResaDatatableFilter[$row->equivalentSql]['libelle'] != '') {
						$obj->nom = $jsonResaDatatableFilter[$row->equivalentSql]['libelle'];
					}
					$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($row->equivalentSql, $configFilter)) ? '1' : '';
					$dynFields[$obj->code] = $obj;

					## on ajoute le statut document
					if ($row->idType == 4) {
						$obj2 = clone $obj;
						$obj2->code .= '__statut_doc';
						$obj2->equivalentSql .= '__statut_doc';
						$obj2->nom = 'Statut document : '.$obj2->nom;
						$obj2->idTypeHtml = 3;
						$obj2->sourceListe = 'statut_docs';
						$obj2->table = '';
						if ($jsonResaDatatableFilter) {
							$activeFields['resaRow'][$obj2->code] =
							$obj2->checked = array_key_exists($obj2->code, $jsonResaDatatableFilter);
						}
						$dynFields[$obj2->code] = $obj2;
						if ($row->renouvelable) {
							$obj3 = clone $obj;
							$obj3->code .= '__fin_validite_doc';
							$obj3->equivalentSql .= '__fin_validite_doc';
							$obj3->nom = 'Fin validité document : '.$obj3->nom;
							$obj3->idTypeHtml = 2;
							$obj3->table = '';
							if ($jsonResaDatatableFilter) {
								$activeFields['resaRow'][$obj3->code] =
								$obj3->checked = array_key_exists($obj3->code, $jsonResaDatatableFilter);
							}
							$dynFields[$obj3->code] = $obj3;
						}
					}
				}
			}

			## Ajout des pseudo-champs de statut des signatures de document
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$tableTMD	= $this->getTableObjet('type_modeles_docs');
			$select		= $tableTMD->getSql()->select();
			$select->where("active=1 AND imprimableEnLot=1 AND idApiSignature IS NOT NULL");
			$resultSet	= $tableTMD->selectWith($select);
			if ($resultSet) {
				foreach ($resultSet as $modele) {
					$obj3			= new Champs();
					$obj3->code		=
					$obj3->equivalentSql	= 'libre_'.$modele->code.'__statut_signature_doc';
					$obj3->nom		= 'Statut signature '.$modele->code;
					$obj3->idTypeHtml	= 3;
					$obj3->sourceListe	= 'etat_contrat';
					$obj3->table		= '';
					if ($jsonResaDatatableFilter) {
						$activeFields['resaRow'][$obj3->code] =
						$obj3->checked = array_key_exists($obj3->code, $jsonResaDatatableFilter);
					}
					$dynFields[$obj3->code] = $obj3;
				}
			}
		}

		## champs catalogue
		$tableCF = $this->getTableObjet('champs_formulaires');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'standard' AND equivalentSql LIKE 'catalogues_%'");
		$resultSet = $tableCF->selectWith($select);
		foreach ($resultSet as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$obj->idTypeHtml = $row->idType;
			$obj->table = 'catalogue_reservation';
			if ($jsonResaDatatableFilter) {
				$activeFields['resaRow'][$obj->code] =
				$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
			}

			$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($row->equivalentSql, $configFilter)) ? '1' : '';
			$dynFields[$obj->code] = $obj;
		}

		## champs suivis
		$tableCF = $this->getTableObjet('champs_suivis');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'libre'");
		$champsSuivis = $tableCF->selectWith($select);

		if ($champsSuivis) {
			foreach ($champsSuivis as $row) {
				$_code	= $row->equivalentSql;

				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;
					$dynFields[$_code] = $obj;
				} else {
					if($row->idType == 19) {
						$row->idType = $this->getGlobalHelper()->getTypeChampFormuleDate($row->id, 'suivis');
					}
					$obj = new \stdClass();
					$obj->table = 'champs_suivis';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idTypeSuivis = $row->idTypeSuivis;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['resaRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}
					$dynFields[$obj->code] = $obj;
				}
			}
		}

		## champs dynamiqueq catalogues
		$tableCF = $this->getTableObjet('champs_catalogue');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'libre'");
		$champsCatalogues = $tableCF->selectWith($select);

		if ($champsCatalogues) {
			foreach ($champsCatalogues as $row) {
				$_code	= $row->equivalentSql;

				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;
					$dynFields[$_code] = $obj;
				} else {
					$obj = new \stdClass();
					$obj->table = 'champs_catalogue';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idTypeCatalogue = $row->idTypeCatalogue;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['resaRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}
					$dynFields[$obj->code] = $obj;
				}
			}
		}

		## Prise en compte champs logements
		$tableObj = new Tables('champs_logements', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select1 = $tableObj->getTable()->getSql()->select();
		$select1->where('idTheme IN (1,2,3)');
		$select1->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select1);

		if ($themeResult) {
			$fieldType = 'resaRow';
			foreach ($themeResult as $row) {
				if ($jsonResaDatatableFilter) {
					$activeFields[$fieldType][$row->code] = $row;
					$row->checked = array_key_exists($row->code, $jsonResaDatatableFilter);
				}
				$resaFields[$row->code] = $row;
			}
		}

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : count_resaFields=".count($resaFields)." count_dynFields=".count($dynFields));

		##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keys_resaFields=".json_encode(array_keys($resaFields)));
		##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keys_dynFields=".json_encode(array_keys($dynFields)));

		##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : resaFields=".json_encode($resaFields));
		##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dynFields=".json_encode($dynFields));
		return array(
			'resaFields' 	=> $resaFields,
			'dynFields' 	=> $dynFields,
			'activeFields'	=> $activeFields,
		);
	}

	private function getlisteChampsAffiches($jsonResaDatatableFilter, $formFields, $mode = 'resa')
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");

		## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$listeChampsAffiches	= array(
			'idLocataire' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
			'idReservation' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
		);

		if ($mode == 'dp') {
			$listeChampsAffiches = array(
				'idDp' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'domiciliations', 'equivalentSql' => 'id', 'visible' => false),
				'idLocataire' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'domiciliations', 'equivalentSql' => 'idLocataire', 'visible' => false),
			);
		}


		if ($jsonResaDatatableFilter && $formFields) {
			foreach ($jsonResaDatatableFilter as $fieldName => $field) {
				if ($fieldName == 'idDp' || $fieldName == 'idLocataire' || $fieldName == 'idReservation') {
					$listeChampsAffiches[$fieldName]['visible'] = true;
				}
				if ($fieldName && !array_key_exists($fieldName, $listeChampsAffiches)) {
					## Recherche du champ dans les différentes listes de champs
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					foreach ($formFields as $_typeField => $_fields) {
						if ($_typeField == "activeFields") {
							continue;
						}

						if (($_field = $_fields[$fieldName])) {
							if ($_typeField == 'dynFields') {
								$listeChampsAffiches[$fieldName] = array(
									'dyn' => 1,
									'typeField' => $_typeField,
									'idTypeHtml' => $_field->idTypeHtml,
									'table' => $_field->table,
									'idChamp' => $_field->idChamp,
									'equivalentSql' => $_field->equivalentSql,
									'sourceListe' => $_field->sourceListe,
									'visible' => true);
								if ($_field->table == "champs_suivis" && $_field->idTypeSuivis) {
									$listeChampsAffiches[$fieldName]['idTypeSuivis'] = $_field->idTypeSuivis;
								}
							} else {
								$listeChampsAffiches[$fieldName] = array(
									'dyn' => 0,
									'typeField' => $_typeField,
									'idTypeHtml' => $_field->idTypeHtml,
									'table' => $_field->table,
									'idChamp' => $_field->id,
									'equivalentSql' => $_field->equivalentSql,
									'sourceListe' => $_field->sourceListe,
									'visible' => true);
							}
							break;
						}
					}
				}
			}
		}
		return $listeChampsAffiches;
	}


	public function annuleraffectationMassAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {

			/*$data = $request->getPost('data');//ids des résa
			foreach($data as $row):
				$this->getResaTable()->updateResa(array('etat'=>2),array('id'=>$row));
			endforeach;*/

			$idsResa = $request->getPost('data');//ids des résa

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idsResa=".json_encode($idsResa));
			$msg = "";
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					$upData = array();
					$upData['idLogement'] = null;

					$upData['numeroChambre'] = null;
					$upData['etat'] = 1;

					$this->getResaTable()->updateResa($upData, array('id' => $resa->id));
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : end");

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => '',
				//'calendar'=>$calendar,
				//'gotoThisDate'=>$gotoThisDate,
				'msg' => "Validation bien faite",
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function refusresaAction()
	{
		$request = $this->getRequest();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] POST=".json_encode($request->getPost()));
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$typeRefus = (int) $request->getPost('type');//4 refus gest, 12 refus etudiant
			$RefusComment = $request->getPost('RefusComment');
			$RefusComment = trim($RefusComment);
			$msg = "";
			if (!empty($idsResa) && $typeRefus > 0) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					$this->getResaTable()->updateResa(array('etat' => $typeRefus, 'RefusComment' => $RefusComment), array('id' => $resa->id));

					## La réservation a-t-elle été créée par un SIG ?
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## $resa	= $this->getResaTable()->getResaWithSig($id); inutile car getResaIn remonte aussi la table reservations_apisig
					if ($resa->idApiSig && $resa->idReservationSig) {
						try {
							$this->initSIG($resa->idApiSig ?: 1, $resa->id);

							## Traitement en fonction du SIG
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if ($this->sig) {
								$this->sig->annulerResa($resa, $RefusComment);
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." Impossible d'initialiser le SIG");
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
							## On continue quand même normalement
						}
					}
				
					//envois des email
					# si gestionnaire 4 => type id 18
					# si etudiant 12 => type id 17
					try{
						if ($typeRefus == 4) {
							$this->envoyerMail($resa->id, 18);
						} elseif ($typeRefus == 12) {
							$this->envoyerMail($resa->id, 17);
						}

						//on vide le planning
						$this->deleteRowPlanningBredea($resa->id);
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
					}
				}
				$msg = "Validation bien faite";
				$success = true;
			} else {
				$success = false;
				$msg = "Erreur validation";
			}

			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => '',
						'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function lirePasDeFacture($idResa)
	{
		$return = null;
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$resa = $this->getResaTable()->getResaWithPms($idResa);
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					if ($resa->numDossier && $resa->codeSite) {
						$return = $bredea->lirePasDeFacture(array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre, 'typeRetour' => 'array'));//retourn 0 ou array si existe
					}
					$bredea->closeConnect();
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				//echo $ex->getMessage();
			}
		}
		return $return;
	}


	## Mise à jour du modèles de facture
	public function majModeleFacture($idResa)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$resa = $this->getResaTable()->getResaWithPms($idResa);
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					if ($resa->numDossier && $resa->codeSite) {
						$loyer = 0;
						$log = $this->getLogementTable()->getLogement($resa->idLogement);
						$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if($modeCamp && $modeCamp->modeAffModeleFacture == 'grilleTarifs') {
							$loyer = 0;//ne pas maj le loyer
						} else {
							if ($log && $log->loyer > 0) {
								$loyer = $log->loyer;
							}
						}
						$prestaLoyerMultiple = array();
						if ($log && $conf->prestaLoyerMultiple == 1) {
							
							if ($conf->prestaLoyerHC && $log->loyerHC > 0) {
								$prestaLoyerMultiple[$conf->prestaLoyerHC] = $log->loyerHC;
							}
							if ($conf->prestaCharges && $log->charges > 0) {
								$prestaLoyerMultiple[$conf->prestaCharges] = $log->charges;
							}
							if ($conf->prestaComplementLoyer && $log->complementLoyer > 0) {
								$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $log->complementLoyer;
							}
				
						}

						$bredea->prepFactureDossier($resa->numDossier, $resa->codeSite, $resa->pasDeFacture, 0, array('loyer' => $loyer, 'prestaLoyerMultiple' => $prestaLoyerMultiple));
					}
					$bredea->closeConnect();
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				//echo $ex->getMessage();
			}
		}
	}

	//desistement en cours de resa
	public function desisterresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$msg = "";
			$success = false;
			$DesistComment = $request->getPost('DesistComment');
			$DesistComment = trim($DesistComment);
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					$majPasDeFacture = false;
					$upData = array('etat' => 13, 'DesistComment' => $DesistComment, 'pasDeFacture' => 1);
					if ($resa->codeSite && $resa->numDossier) {
						$campagneMode = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if (!$campagneMode || $campagneMode->nePasMajPasDeFacture != 1) {
							$upData['pasDeFacture'] = 1;
							$majPasDeFacture = true;
						}
					}
					$this->getResaTable()->updateResa($upData, array('id' => $resa->id));
					//on efface la ligne de la pile si existe
					$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $resa->id))->current();
					if ($pile) {
						$this->getTableObjet('pile_paiement')->delete(array('id' => $pile->id));
					}

					## La réservation a-t-elle été créée par un SIG ?
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## $resa	= $this->getResaTable()->getResaWithSig($id); inutile car getResaIn remonte aussi la table reservations_apisig
					if ($resa->idApiSig && $resa->idReservationSig) {
						try {
							$this->initSIG($resa->idApiSig ?: 1, $resa->id);

							## Traitement en fonction du SIG
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if ($this->sig) {
								$this->sig->annulerResa($resa, $DesistComment);
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=".$resa->idApiSig." idResa=".$resa->id." Impossible d'initialiser le SIG");
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=[".$ex->getMessage()."]");
							## On continue quand même normalement
						}
					}

					//envois de mail desistement pris en compte moins 1 mois type 19 si periode < 1 mois
					// sinon on envois plus un mois id 20

					$now = date('Y-m-d');
					$dateDebut = new \DateTime($resa->dateArrivee);
					$dateFin = new \DateTime($now);
					$difference = $dateDebut->diff($dateFin);

					$intervalCalculer = $difference->format('%m');

					if ($intervalCalculer < 1) {
						//echo "moins un mois";
						$this->envoyerMail($resa->id, 19);
					} else {
						//echo "plus un mois";
						$this->envoyerMail($resa->id, 20);
					}
					$this->deleteRowPlanningBredea($resa->id);
					## maj de modèle de facture : pasDeFacture = 1
					if ($majPasDeFacture) {
						$this->majModeleFacture($resa->id);
					}
					$success = true;
				}
			}
			$msg = $success ? "Validation bien faite" : "Erreur validation";
			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => '',
						'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	// valider desistement en cours de resa
	public function validerdesistementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$msg = "";
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					//on verife si il a pas de solde
					$passer = true;
					if ($resa->numDossier && $resa->codeSite) {
						$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
						$msgSolde = $this->checksoldebredea($cData);
						if ($msgSolde != "") {
							$msg .= $msgSolde."<br>";
							$passer = false;
						}
					}
					if ($passer) {
						$this->getResaTable()->updateResa(array('etat' => 14), array('id' => $resa->id));
					}
				}
			}
			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => '',
						'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	// Annuler desistement d'une résa : on la remis à demande validée
	public function annulerdesistementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$msg = "";

			//$fraisParResa = $this->getSoldeComptesResa($idsResa, array(13,14));//13 : desistement en cours, 14 validée
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					//on verife si il a pas de solde
					$passer = true;
					if ($resa->numDossier && $resa->codeSite) {
						$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
						$msgSolde = $this->checksoldebredea($cData);
						if ($msgSolde != "") {
							$msg .= $msgSolde."<br>";
							$passer = false;
						}
					}/*elseif($resa->numResa && $resa->codeSite){
						$solde = !empty($fraisParResa[$resa->id]) ? $fraisParResa[$resa->id] : 0;
						if($solde==0){
							$msg.= "Vous ne pouvez pas annuler le désistement de cette résa numResai ".$resa->numResa." ".$resa->codeSite." :  solde compte $solde<br>";
							$passer = false;
						}
					}*/
					if ($passer) {
						//on archive le dossier / resai bredea
						$archive = false;
						$numResStr = "";
						if ($resa->numDossier && $resa->codeSite) {
							$numResStr = " numDossier ".$resa->numDossier." ".$resa->codeSite;
							$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
							$cData['type'] = 'dossier';
							$archive = $this->archiverBredea($cData);
						} elseif ($resa->numResa && $resa->codeSite) {
							$numResStr = " numDossier ".$resa->numResa." ".$resa->codeSite;
							$cData = array('numResa' => $resa->numResa, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
							$cData['type'] = 'resa';
							$archive = $this->archiverBredea($cData);
						}
						if ($archive) {
							//on remis le logement à dispo
							$this->getLogementTable()->updateLogement(array('idEtat' => '1'), array('id' => $resa->idLogement));

							// on maj numDossier, codeSite, numResa, idPMS a null, et etat = 1, idLogement, numeroChambre
							$upData = array();
							$upData['numDossier'] = null;
							$upData['numResa'] = null;
							$upData['idPMS'] = null;
							$upData['codeSite'] = null;
							$upData['idLogement'] = null;
							$upData['numeroChambre'] = null;
							$upData['pasDeFacture'] = 0;
							$upData['etat'] = 1;
							$this->getResaTable()->updateResa($upData, array('id' => $resa->id));

							// on re ajoute la demande dans bredea
							$this->ajouterDemandeBredea($resa->id);
						} else {
							$msg .= "Problème archivage résa $numResStr <br>";
						}
					}
				}
			}
			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => '',
						'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## retourné les desistements validée en demande validée, et proposer d'archivé le désistement validé
	public function retournerDesistementEnDemandeAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$msg = "";
			$tableResa = $this->getTableObjet('reservations');
			$tableVD = $this->getTable('valeurs_dynamiques');
			$tableComptes = $this->getTable('comptes');
			$idsValide = array();
			if (!empty($idsResa)) {
				//$resas = $this->getResaTable()->getResaIn($idsResa);
				$select = $tableResa->getSql()->select();
				$select->where->in('id', $idsResa);
				$resas = $tableResa->selectWith($select);
				foreach ($resas as $resa) {
					if ($resa->etat != 14) {
						continue;
					}//on traite que les desistement validés
					## copie de la réservation
					$newResa = clone $resa;
					$newResa->id = 0;
					$newResa->etat = 1;
					$newResa->idLogement = null;
					$newResa->numeroChambre = null;
					$newResa->idTypeLogementAttribue = null;
					$newResa->idPMS = null;
					$newResa->numResa = null;
					$newResa->numDossier = null;
					$newResa->codeSite = null;

					$dataResa = get_object_vars($newResa);
					$tableResa->insert($dataResa);
					$idNewReservation = $tableResa->lastInsertValue;

					## copie des valeurs dynamiques
					$valeursDeLoc = $tableVD->select(array('idLocataire' => $resa->idLocataire, 'idReservation' => $resa->id));
					foreach ($valeursDeLoc as $vl) {
						//on maj idReservation
						$vData = array();
						$vData['idLocataire'] = $vl->idLocataire;
						$vData['idReservation'] = $idNewReservation;
						$vData['valeur'] = $vl->valeur;
						$vData['idChamp'] = $vl->idChamp;
						$vData['statutDoc'] = $vl->statutDoc;
						$tableVD->insert($vData);
					}
					## copie des choix de logement
					$choix = $this->getChoixTable()->getChoixDeReservation($resa->id);
					foreach ($choix as $c) {
						$ch = $c;
						$ch->idReservation = $idNewReservation;
						$ch->id = 0;
						$this->getChoixTable()->saveChoix($ch);
					}

					## copie des lignes compte, si le mode de validation campagne = 3
					$modeValidationCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
					if ($modeValidationCamp && $modeValidationCamp->modeValidationDemande == 3) {
						$compteRows = $tableComptes->select(array('idReservation' => $resa->id));
						foreach ($compteRows as $compte) {
							$compte->id = 0;
							$compte->idReservation = $idNewReservation;
							$compte->etat = null;
							$compte->dateM = date('Y-m-d');
							$compte->credit = 0;
							$compte->solde = $compte->debit;
							$compte->nature = "";
							$compte->idPaiement = null;
							$dataCompte = get_object_vars($compte);
							$tableComptes->insert($dataCompte);
						}
					}

					## ajout de demande dans bredea
					$numDem = $this->ajouterDemandeBredea($idNewReservation);
					$idsValide[] = $resa->id;

					if (!$numDem) {
						$msg .= "Erreur ajout demande dans bredea<br>";
					}
				}
			}
			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => '',
						'msg' => $msg,
						'idsValide' => $idsValide,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	private function getSoldeComptesResa($idsResa = array(), $etatResa = array())
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$totalFraisParResa = array();
		$etatStr = $idsStr = "";
		if (!empty($idsResa)) {
			$idsStr = implode(',', $idsResa);
		}
		if (!empty($etatResa)) {
			$etatStr = implode(',', $etatResa);
		}
		$table = $this->getTableObjet('comptes');
		$select = $table->getSql()->select();
		$select->columns(array(
			'idReservation',
			'total' => new \Zend\Db\Sql\Expression('SUM(comptes.solde)'),
		));
		$select->join('reservations', 'reservations.id =comptes.idReservation', array('idResa' => 'id'));
		$select->where("reservations.etat IN ($etatStr) AND reservations.id IN ($idsStr) AND reservations.archive='0'");
		$select->group('comptes.idReservation');
		$resultSet = $table->selectWith($select);
		foreach ($resultSet as $row) {
			$totalFraisParResa[$row->idReservation] = $row->total;
		}
		return $totalFraisParResa;
	}

	//mise en attente d'une demande de reservation
	public function miseenattenteAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idsResa=".json_encode($idsResa));
			$msg = "";
			$success = false;
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					if ($resa->etat == 1) {
						$this->getResaTable()->updateResa(array('etat' => 11), array('id' => $resa->id));
						$success = true;
						//envois de mail, Demande mise en attente
						$this->envoyerMail($resa->id, 25);
					} else {
						$msg .= "Résa ID ".$resa->id." en etat différent de Demande validée<br>";
					}
				}
			}
			//$msg = $success ? "" : "Erreur validation";
			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => '',
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//remise en validation d'une demande de reservation
	public function remiseendemandeAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idsResa=".json_encode($idsResa));
			$msg = "";
			$success = false;
			if (!empty($idsResa)) {
				$resas = $this->getResaTable()->getResaIn($idsResa);
				foreach ($resas as $resa) {
					$this->getResaTable()->updateResa(array('etat' => 1), array('id' => $resa->id));
					$success = true;
				}
			}
			$msg = $success ? "" : "Erreur validation";
			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => '',
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//demande signature du contrat
	public function signaturecontratAction()
	{
		$confTable = $this->getConfigurationTable();
		$conf = $confTable->getConfig(1);
		#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : class:configurationTable=".get_class($confTable)." conf=".json_encode($conf));

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('data');//ids des résa
			$msg = "";
			$success = false;
			if (!empty($idsResa)) {
				///actions a faire
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idsResa=".json_encode($idsResa));

				//-------------------------------------------------------------------------------------------------------------------------
				#$idModele = $request->getPost('idModele');
				$idModele = 9;	// CTHES - Contrat d'hébergement de type E-signé

				##PDF MERGING
				#include(getcwd().'/externalibs/PDFMerger/PDFMerger.php');

				#$methods	= get_class_methods($this);
				#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : nbMethodes=".count($methods));
				#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : Methodes=".json_encode($methods));

				$myApiSignatureTable = $this->getApisignatureTable();
				$myApiSignature = $myApiSignatureTable->getActiveApi();
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : class_myApiSignature=".get_class($myApiSignature)." myApiSignature=".json_encode($myApiSignature));

				if ($myApiSignature->id) {
					## Une interface de signature a été configurée
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$myApiSettingSignatureTable = $this->getApisettingsignatureTable();
					$myApiSettingSignature	= $myApiSettingSignatureTable->getAPISettingArray($myApiSignature->id);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : myApiSettingSignature=".json_encode($myApiSettingSignature));

					$signatures	= new SignatureController();
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : SignatureController=".get_class($signatures));

					## Init des tables tant que getLocator ne fonctionne pas !!
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$signatures->setResaTable($this->getResaTable());
					$signatures->setLocataireTable($this->getLocataireTable());
					$signatures->setLogementTable($this->getLogementTable());
					$signatures->setBatimentTable($this->getBatimentTable());
					$signatures->setDocumentTable($this->getDocumentTable());
					$tableDocumentLocataire = new Tables('document_locataire', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));


					## Init et vérification de l'api de signature
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$err	= $signatures->init($myApiSignature, $myApiSettingSignature);
					if (!$err) {
						## Une interface de signature a été configurée et validée
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : signatures->init OK");

						$nbContrats	= 0;
						$msg1	= "Liste des contrats générés<br>";
						foreach ($idsResa as $idResa) {
							## Vérification de l'état de signature du document
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$docResa	= null;
							$docsResa	= $this->documentTable->getAllDocumentByReservation($idResa);
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : nbRows=".$docsResa->count());
							if ($docsResa) {
								foreach ($docsResa as $doc) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : doc=".json_encode($doc));
									if ($doc->idTypeDocument == 6 && $doc->signState > 0) {
										$docResa	= $doc;
										break;
									}
								}
							}
							if ($docResa) {
								## Un contrat est déjà créé
								## ~~~~~~~~~~~~~~~~~~~~~~~~
								if ($docResa->signState == 4) {
									$msg1	.= "resaId=$idResa : déjà signé<br>";
								} else {
									$msg1	.= "resaId=$idResa : en cours de signature<br>";
								}
								continue;
							}

							if (1) {
								## Génération du document .pdf de contrat personnalisé
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => false, 'avecSignature' => true);
								$returnUrl = $this->genererModeleDocument($idResa, "", $idModele, $options);
							}

							if (1) {
								$nbContrats++;

								## Lancement de l'invitation à signer
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$ret	= $signatures->createAndSendInvitation($idResa, $returnUrl);
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idResa=$idResa ret=".json_encode($ret));

								if ($ret[cr]) {
									## Erreur dans l'invitation
									## ~~~~~~~~~~~~~~~~~~~~~~~~
								} else {

									## Insertion du document .pdf dans la table des documents
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$doc			= new Document();
									$doc->nom		= basename($returnUrl);
									$doc->idTypeDocument	= 7;
									$doc->langue		= "fr_FR";
									$doc->signDocId		= $ret[contratUid];
									$doc->signState		= 2;	// INVITED1
									$docId			= $this->getDocumentTable()->saveDocument($doc);

									## Insertion du lien entre document et locataire
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$tableDocumentLocataire->getTable()->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
								}
								$msg1	.= "resaId=$idResa : OK<br>";
							} else {
								$msg1	.= "resaId=$idResa : KO<br>";
							}
						}

						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : nbContrats=$nbContrats msg1=$msg1");

						$view = new JsonModel(array(
							'success' => true,
							'htmlOP' => 'htmlOP ??',
							'msg' => $msg1,
							));

						$view->setTerminal(true);
						return $view;
					} else {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : signatures->init ERR=$err");
					}
				}

				//-------------------------------------------------------------------------------------------------------------------------
			}
			$msg = $success ? "" : "Erreur validation";
			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => '',
				'msg' => $msg,
				));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function deleteRowPlanningBredea($idResa)
	{
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					if ($resa && $resa->numDossier) {
						$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'numLog' => $resa->numeroChambre, 'dateArrivee' => $resa->dateArrivee);
						$rep = $bredea->deleteRowFromPlanning($cData);
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
	}


	private function checksoldebredea($cData = array(), $idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$msg = "";
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();
					if (!empty($cData)) {
						$soldes = $bredea->getSoldeDossier($cData);
						//print_r($soldes);exit();

						if (!empty($soldes)) {
							$soldeCompte = !empty($soldes['soldeCompte']) ? $soldes['soldeCompte'] : 0;
							$soldeCaution = !empty($soldes['soldeCaution']) ? $soldes['soldeCaution'] : 0;
							if ($soldeCompte == 0 && $soldeCaution == 0) {
								//on fait rien
							} else {
								if ($soldeCompte != 0) {
									$msg = "Vous ne pouvez pas supprimer cette réservation dossier ".$cData['numDossier']." site ".$cData['codeSite'].", SOLDE COMPTE $soldeCompte<br>";
								}
								if ($soldeCaution != 0) {
									$msg .= "Vous ne pouvez pas supprimer cette réservation dossier ".$cData['numDossier']." site ".$cData['codeSite'].", SOLDE CAUTION $soldeCaution";
								}
							}
						}
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $msg;
	}

	// retourne la plage de dates pour les champs de type date
	private function getPlageDeDate($idChamp)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idChamp=$idChamp");

		$datesPlage = array();
		//plages de dates
		$plage = $this->getTable('champs_dateinterval')->select(array('idChamp' => $idChamp))->current();
		if ($plage) {
			$plageMin = $plageMax = "";
			$uniteMin = $uniteMax = "d";
			if ($plage->dateMin == 'limited') {
				$plageMin = $plage->nombreJoursMin;
				if ($plage->uniteMin == "year") {
					$uniteMin = "y";
				} elseif ($plage->uniteMin == "month") {
					$uniteMin = "m";
				} elseif ($plage->uniteMin == "week") {
					$uniteMin = "w";
				} else {
					$uniteMin = "d";
				}
			}
			if ($plage->dateMax == 'dateNow' || $plage->dateMax == 'limited') {
				//dateNow : date du jour +- X unite
				//$plageMax = '-1';
				$plageMax = $plage->nombreJoursMax;
				if ($plage->uniteMax == "year") {
					$uniteMax = "y";
				} elseif ($plage->uniteMax == "month") {
					$uniteMax = "m";
				} elseif ($plage->uniteMax == "week") {
					$uniteMax = "w";
				} else {
					$uniteMax = "d";
				}
			}

			//cas date fixe avec annee dynamique
			if ($plage->dateMinFixe && $plage->uniteMin == 'year') {
				//on recupère l'année en cours, puis on y rajoute ou on diminue le nombre configuré
				$thisYear = date('Y');
				//on recupère le jour et mois de $plage->dateMinFixe
				$mj = date('m-d', strtotime($plage->dateMinFixe));
				$plage->dateMinFixe = $thisYear.'-'.$mj;
				if ($plage->nombreJoursMin > 0) {
					$plage->dateMinFixe = date('Y-m-d', strtotime($plage->dateMinFixe." + ".$plage->nombreJoursMin." year"));
				} elseif ($plage->nombreJoursMin < 0) {
					$plage->nombreJoursMin = abs($plage->nombreJoursMin);//on converti en positive
					$plage->dateMinFixe = date('Y-m-d', strtotime($plage->dateMinFixe." - ".$plage->nombreJoursMin." year"));
				}
			}

			if ($plage->dateMaxFixe && $plage->uniteMax == 'year') {
				//on recupère l'année en cours, puis on y rajoute ou on diminue le nombre configuré
				$thisYear = date('Y');
				//on recupère le jour et mois de $plage->dateMaxFixe
				$mj = date('m-d', strtotime($plage->dateMaxFixe));
				$plage->dateMaxFixe = $thisYear.'-'.$mj;
				if ($plage->nombreJoursMax > 0) {
					$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMaxFixe." + ".$plage->nombreJoursMax." year"));
				} elseif ($plage->nombreJoursMax < 0) {
					$plage->nombreJoursMax = abs($plage->nombreJoursMax);//on converti en positive
					$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMaxFixe." - ".$plage->nombreJoursMax." year"));
				}

				//test de control de plage
				if ($plage->dateMinFixe && strtotime($plage->dateMinFixe) > strtotime($plage->dateMaxFixe)) {
					//on les converti
					$tmp = $plage->dateMinFixe;
					$plage->dateMinFixe = $plage->dateMaxFixe;
					$plage->dateMaxFixe = $tmp;
				}
			} elseif ($plage->dateMinFixe && $plage->uniteMin == 'year' && $plageMax != 0 && $plage->dateMax != 'dateNow') {
				if ($plageMax > 0) {
					$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." + ".$plageMax." ".$plage->uniteMax));
				} else {
					$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." - ".abs($plageMax)." ".$plage->uniteMax));
				}
			}
			//date min +- X unite
			if (($plage->dateMax == 'limited' || $plage->dateMax == 'dateNow') && !$plage->dateMaxFixe) {
				//limited : date min + X unite
				$uMin = $plage->uniteMin ? $plage->uniteMin : "day";
				$uMax = $plage->uniteMax ? $plage->uniteMax : "day";
				$now = date('Y-m-d');
				if ($plage->dateMax == 'dateNow') {
					$opMax = $plage->nombreJoursMax > 0 ? '+' : '';
					$plage->dateMaxFixe = date('Y-m-d', strtotime($now." $opMax ".$plage->nombreJoursMax." ".$uMax));
				} else {
					if ($plage->dateMinFixe) {
						$plage->dateMaxFixe = date('Y-m-d', strtotime($plage->dateMinFixe." $opMax ".$plage->nombreJoursMax." ".$uMax));
					} else {
						$opMin = $plage->nombreJoursMin > 0 ? '+' : '';
						$opMax = $plage->nombreJoursMax > 0 ? '+' : '';
						$dateMin = date('Y-m-d', strtotime($now." $opMin ".$plage->nombreJoursMin." ".$uMin));
						$plage->dateMaxFixe = date('Y-m-d', strtotime($dateMin." $opMax ".$plage->nombreJoursMax." ".$uMax));
					}
				}
			}

			$datesPlage[$champ->id] = array('plageMin' => $plageMin,
											'plageMax' => $plageMax,
											'uniteMin' => $uniteMin,
											'uniteMax' => $uniteMax,
											'dateMin' => $plage->dateMinFixe,
											'dateMax' => $plage->dateMaxFixe,
											);
		}

		## arrivee + depart, intervals selon le canal

		return $datesPlage;
	}

	public function correctDateFormat($listeChampsAffiches, $rows)
	{
		## Construire une liste des champs avec dates
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$colDates	= array();
		if ($listeChampsAffiches) {
			foreach ($listeChampsAffiches as $_colName => $_col) {
				if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
					$colDates[]	= $_colName;
				}
			}
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

		if ($colDates) {
			$rows1	= array();
			foreach ($rows as $key => $row) {
				foreach ($colDates as $_colName) {
					$rowValue	= $row[$_colName];
					if ($rowValue && strpos($rowValue, '-') == 2) {
						## Date au format dd-mm-yyyy -> il faut convertir
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						list($dd, $mm, $yyyy)	= explode("-", $rowValue);
						$row[$_colName]		= "$yyyy-$mm-$dd";
					}
				}
				$rows1[]	= $row;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rows1=".count($rows1));
			return $rows1;
		}
		return $rows;
	}

	##Action : edition de champs dans la liste
	public function editchampAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa', 0);
			$isResa = (int) $request->getPost('isResa', 0);
			$champCode = $request->getPost('champCode');
			$actualValue = $request->getPost('actualValue');
			$actualValue = trim($actualValue);
			$idDp = (int) $request->getPost('idDp', 0);
			$mode = (int) $request->getPost('mode', '');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isResa=$isResa idResa=$idResa champCode=$champCode actualValue=$actualValue");

			$params = array('idResa' => $idResa,
							'isResa' => $isResa,
							'champCode' => $champCode,
							'actualValue' => $actualValue,
							'idDp' => $idDp,
							'mode' => $mode,
							'modeEditionInline' => 1,
							 );
			$return = $this->editChampInline($params);

			$htmlOP = !empty($return['htmlOP']) ? $return['htmlOP'] : "";
			$champName = !empty($return['champName']) ? $return['champName'] : "";
			$obligatoire = !empty($return['obligatoire']) ? $return['obligatoire'] : 0;



			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa champName=$champName obligatoire=$obligatoire htmlOP=$htmlOP");

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOP,
				'champName' => $champName,
				'obligatoire' => $obligatoire,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function editChampInline($params = array())
	{
		extract($params);
		if (!array_key_exists('modeEditionInline', $params)) {
			$modeEditionInline = "";
		}
		$htmlOP = "";
		$champName = "";
		$obligatoire = 0;
		$value = null;
		$editer = true;
		if (!$idDp) {
			//on interdit le changement de date de depart de l ancienne resa si la resa est en cours de changement
			$resa = $this->getResaTable()->getResa($idResa);
			if ($resa && $resa->idNouvelleResa && $champCode == "dateDepart") {
				$nr = $this->getResaTable()->getResa($resa->idNouvelleResa);
				if ($nr && $nr->etat == 15) {
					$editer = false;
				}
			}
			//aussi on interdit le changement de la date arrivee du nouveau logement, si en cours de changement
			if ($resa && $resa->etat == 15) {
				$editer = false;
			}
		}

		if ($editer && $champCode != "idReservation" && $champCode != "idLocataire" && $champCode != "id") {
			//on recupere l equivalent sql du champ par code, dans la table champs
			//$champ  = $this->getTable('champs')->select(array('code'=>$champCode))->current();
			//$champ  = $this->getTable('champs_formulaires')->select(array('equivalentSql'=>$champCode))->current();
			if ($idDp) {
				$champ  = $this->getChampDynByDp($champCode, $idDp);
			} else {
				$champ  = $this->getChampDynByResa($champCode, $idResa);
			}

			if (!$champ) {
				$where = array('equivalentSql' => $champCode);
				if ($idDp && $champCode == "etat") {
					$where['table'] = 'domiciliations';
				}

				$champ = $this->getTableObjet('champs')->select($where)->current();
				if (!$champ) {
					//si pas trouve on cherche via le code
					$where = array('code' => $champCode);
					if ($idDp && $champCode == "etatDp") {
						$where['table'] = 'domiciliations';
					}
					$champ  = $this->getTable('champs')->select($where)->current();
				}

				if ($champ) {
					$value = $actualValue;
				}
			} else {
				$value = $actualValue;
			}
			## Traitement cas choix de résidence residence1, residence2 etc
			if($champ && !$champ->equivalentSql && substr($champ->code, 0, -1) == 'residence') {
				$champ->equivalentSql = 'idResidence';
			}
			if ($champ && $champ->equivalentSql) {
				if ($idDp) {
					$htmlOP = $this->getInput($champ->equivalentSql, 1, 1, $value, array('validerFichier' => true, 'idDp' => $idDp, 'code' => $champCode, 'modeEditionInline' => $modeEditionInline));
				} else {
					$htmlOP = $this->getInput($champ->equivalentSql, 1, 1, $value, array('validerFichier' => true, 'idResa' => $idResa, 'modeEditionInline' => $modeEditionInline, 'code' => $champCode));
				}
				$champName = $champ->equivalentSql;
				//$chForm = $this->getTable('champs_formulaires')->select(array('equivalentSql'=>$champName))->current();
				$chForm = $champ;
				if ($chForm && property_exists($chForm, 'obligatoire') && $chForm->obligatoire == 1) {
					$obligatoire = 1;
				}
			}
			if (!$champ && $idResa &&  substr($champCode, -12) == '__statut_doc') {
				$champDoc = substr($champCode, 0, (strlen($champCode) - 12));
				$htmlOP = $this->getInput($champCode, 1, 1, $value, array('validerFichier' => true, 'idResa' => $idResa, 'source' => 'champs_dynamiques', 'modeEditionInline' => $modeEditionInline));
			}
			if (!$champ && $idResa &&  substr($champCode, -18) == '__fin_validite_doc') {
				$champDoc = substr($champCode, 0, (strlen($champCode) - 18));
				$htmlOP = $this->getInput($champCode, 1, 1, $value, array('validerFichier' => true, 'idResa' => $idResa, 'source' => 'champs_dynamiques', 'modeEditionInline' => $modeEditionInline));
			}
		}

		return array('htmlOP' => $htmlOP,
					'champName' => $champName,
					'obligatoire' => $obligatoire );
	}

	public function validereditchamplisteAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa', 0);
			$idDp = (int) $request->getPost('idDp', 0);
			$isResa = (int) $request->getPost('isResa', 0);
			$champCode = $request->getPost('champCode');
			$valeur = $request->getPost('valeur');
			$name = $request->getPost('name');//equivalent sql dans la table champs
			$msg = "";
			if(is_array($valeur)) $valeur = implode(',',array_unique($valeur));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa isResa=$isResa champCode=$champCode name=$name valeur=$valeur");
			$htmlOP = $this->editResaField($idResa, $champCode, $name, $valeur, $isResa, $idDp, $request->getPost());
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa htmlOP=$htmlOP");
			$success = true;
			if (is_array($htmlOP)) {
				$msg = array_key_exists('msg', $htmlOP) ? $htmlOP['msg'] : '';
				$htmlOP = '';
				$success = false;
			} elseif (!empty($this->messages['editionInline']['error'])) {
				$msg = implode('<br />', $this->messages['editionInline']['error']);
				$htmlOP = '';
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'htmlOP' => $htmlOP,
				'msg' => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	private function getChampDynByResa($champCode, $idResa)
	{
		$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
		if (!$resa) {
			return null;
		}
		$tableCF = $this->getTable('champs_formulaires');
		$select = $tableCF->getSql()->select();
		$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
		$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.equivalentSql' => $champCode));
		$champ = $tableCF->selectWith($select)->current();
		return $champ;
	}

	private function getChampDynByDp($champCode, $idDp)
	{
		$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
		if (!$dp) {
			return null;
		}

		$tableCF = $this->getTable('champs_formulaires');
		$select = $tableCF->getSql()->select();
		$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
		$select->where(array('formulaires.idCampagne' => $dp->idCampagne, 'champs_formulaires.equivalentSql' => $champCode));
		$champ = $tableCF->selectWith($select)->current();
		return $champ;
	}

	private function editResaField($idResa, $champCode, $name, $valeur, $isResa = true, $idDp = null, $post = array())
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}


		$tools = new Tools();

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa isResa=$isResa champCode=$champCode valeur=$valeur");
		$htmlOP = "";
		$up = false;
		$initialVal = $valeur;
		$champBase  = $this->getTable('champs')->select(array('code' => $champCode))->current();
		$recalculerPresta = false;

		//$champ  = $this->getTable('champs_formulaires')->select(array('equivalentSql'=>$champCode))->current();
		if ($idDp) {
			$champ = $this->getChampDynByDp($champCode, $idDp);
		} else {
			$champ = $this->getChampDynByResa($champCode, $idResa);
		}

		if (!$champ) {
			$champ = $champBase;
		}

		//maj champs catalogue
		if (strpos($champCode, 'catalogues_') !== false && $valeur > 0) {
			$idTypeCatalogue = str_replace('catalogues_', '', $champ->equivalentSql);
			$options = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue);
			if ($idResa) {
				$this->getCatalogueTable()->insertCatalogueResa($valeur, $idResa);
			} elseif ($idDp) {
				$this->getCatalogueTable()->insertCatalogueDp($valeur, $idDp);
			}
			$htmlOP = $options[$valeur];
			$champ = null;
		}

		## on vérifie si on a un champ statut document
		$champStatutDoc = "";
		$champStatutDocUpdated = false;
		if (!$champ &&  substr($champCode, -12) == '__statut_doc') {
			$champDoc = substr($champCode, 0, (strlen($champCode) - 12));
			$champ = $this->getTableObjet('champs_formulaires')->select(array('equivalentSql' => $champDoc))->current();
			if ($champ) {
				$champ->idTypeHtml = 3;
				$champ->sourceListe = 'statut_docs';
				$champStatutDoc = $champ;
			}
		}
		## on vérifie si on a un champ date fin validite document
		$champFinValiditeDoc = "";
		$champFinValiditeDocUpdated = false;
		if (!$champ &&  substr($champCode, -18) == '__fin_validite_doc') {
			$champDoc = substr($champCode, 0, (strlen($champCode) - 18));
			$champ = $this->getTableObjet('champs_formulaires')->select(array('equivalentSql' => $champDoc))->current();
			if ($champ) {
				$champ->idTypeHtml = 2;
				$champFinValiditeDoc = $champ;
			}
		}
		## Traitement cas champs choix de résidence(residence1, residence2 etc)
		if($champ && !$champ->equivalentSql && substr($champ->code, 0, -1) == 'residence') {
			$champ->table = 'choix_typelogement';
			$champ->equivalentSql = 'idResidence';
			$champ->sourceListe = 'residences';
			$champBase->table = 'choix_typelogement';
		}
		//print_r($champ);exit();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa isResa=$isResa champCode=$champCode champ=".json_encode($champ));
		if (($isResa || $idDp) && $champ && $champ->equivalentSql /*&& $valeur!=""*/) {
			//on check la date
			if ((property_exists($champ, 'idType') && $champ->idType == 2) || (property_exists($champ, 'idTypeHtml') && $champ->idTypeHtml == 2)) {
				$valeur = $valeur ? date('Y-m-d', strtotime($valeur)) : null;
			}
			//on verife si champ de base
			$table = "";
			if ($champBase) {
				$table = $champBase->table;
			} elseif ($champ->nature == 'libre') {
				$table = "valeurs_dynamiques";
			}
			if ($valeur == 'on') {
				$valeur = '1';
			}
			if ($table != "") {
				if ($idResa) {
					$resa = $this->getResaTable()->getResa($idResa);

					if ($resa) {
						// on verifie la disponibilite de date de depart
						if ($champ->equivalentSql == "dateDepart" && $valeur != $resa->dateDepart) {
							$isOccupe = $this->getResaTable()->checkEndDate($valeur, $resa->idLogement, $idResa, array(2, 3, 7, 15));//false => dispo
							$isDispo = $this->checkDisponibiliteLogementBredea($idResa, $valeur);
							$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $resa->dateArrivee, $valeur);
							if (!$isDispo || $isOccupe || $bloquerCSMsg != '') {
								if (!$isDispo) {
									$msg = "Logement non disponible pour la nouvelle date de départ $valeur, veuillez vérifier le planning bredea";
								} elseif ($bloquerCSMsg != '') {
									$msg = $bloquerCSMsg;
								} else {
									$msg = "Logement non disponible pour la nouvelle date de départ $valeur";
								}

								return array('msg' => $msg);
							}
						}

						// on verifie la disponibilite de date arrivée
						if ($champ->equivalentSql == "dateArrivee" && $valeur != $resa->dateArrivee) {
							$isOccupe = $this->getResaTable()->checkStartDate($valeur, $resa->idLogement, $idResa, array(2, 3, 7, 15));//false => dispo
							$isDispo = $this->checkDisponibiliteLogementBredea($idResa, $valeur);
							$bloquerCSMsg = $this->isBloquerCS($resa->idLogement, $valeur, $resa->dateDepart);
							if (!$isDispo || $isOccupe || $bloquerCSMsg != '') {
								if (!$isDispo) {
									$msg = "Logement non disponible pour la nouvelle date arrivée $valeur, veuillez vérifier le planning bredea";
								} elseif ($bloquerCSMsg != '') {
									$msg = $bloquerCSMsg;
								} else {
									$msg = "Logement non disponible pour la nouvelle date arrivée $valeur";
								}

								return array('msg' => $msg);
							}
						}

						$idLocataire = $resa->idLocataire;
						$data = array($champ->equivalentSql => $valeur);

						/*if($table == 'edl') {
							$data = array('remise_des_cles' => $valeur);
							$where = array('id_reservations' => $resa->id);
							$this->getTable($table)->update($data, $where);
						}*/

						if ($table == "locataires") {
							$where = array('id' => $idLocataire);
							$loc = $this->getTable($table)->select($where)->current();

							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($loc, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update usager (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "locataires";
							$log->idReservation = $resa->id;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###

							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa champCode=$champCode update table=$table where=".json_encode($where)." data=".json_encode($data));
							$this->getTable($table)->update($data, $where);

							$up = true;
						} elseif ($table == "reservations") {
							$where = array('id' => $idResa);

							if ($champ->equivalentSql == 'idMenage' && $resa->idMenage != $valeur) {
								$this->saveMenageHistorique($idResa, $resa->idMenage, $valeur);
							}

							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($resa, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update reservation (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "locataires";
							$log->idReservation = $resa->id;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###

							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa colName=$colName where=".json_encode($where)." data=".json_encode($data));
							//print_r($where);print_r($data);exit();
							$this->getTable($table)->update($data, $where);

							## verification dates facturation si changement dates arrivee ou depart
							## si on decale la date d arrive dans le passé, on decale aussi la date debut de facturation
							if (array_key_exists('dateArrivee', $data)) {
								if (strtotime($data['dateArrivee']) < strtotime($resa->dateArrivee)) {
									$this->getTable($table)->update(array('dateArriveeTheorique' => $data['dateArrivee']), array('id' => $resa->id));
								}
							}

							## si on decale la date de depart dans le future, on decale aussi la date fin facturation
							if (array_key_exists('dateDepart', $data)) {
								if (strtotime($data['dateDepart']) > strtotime($resa->dateDepart)) {
									$this->getTable($table)->update(array('dateDepartTheorique' => $data['dateDepart']), array('id' => $resa->id));
								}
							}

							## maj mode paiement presta en virement si rib controller
							//verification si on a déjà les champs RIB rempli
							if (array_key_exists('statutRIB', $data)) {
								$msgCheck = $this->isRIBRempli($idResa);
								if ($msgCheck == 'ok') {
									if ($data['statutRIB'] == 'controler') {
										$this->getPrestaTable()->majModePaiement($idResa, 'Virement');
									}
								} else {
									$this->messages['editionInline']['error'][] = $msgCheck;
									$this->getTable($table)->update(array('statutRIB' => null), array('id' => $idResa));
								}
							}

							## Modification de l'etat de la résa en parti
							if (array_key_exists('dateDepart', $data)) {
								if (strtotime($data['dateDepart']) != strtotime($resa->dateDepart)) {
									$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
									if($modeCamp && $modeCamp->majEtatResaEnParti == 1) {
										if(strtotime($data['dateDepart']) <= strtotime(date('Y-m-d'))) {
											$this->getTable($table)->update(array('etat' => 6), array('id' => $resa->id));
										}
									}
								}
							}


							$up = true;
						} elseif ($table == "valeurs_dynamiques") {
							$data = array('valeur' => $valeur);
							##on récup le bon champ de la bonne campagne
							$champsFormulaireTable = $this->getTableObjet('champs_formulaires');
							$select = $champsFormulaireTable->getSql()->select();
							$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
							$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.equivalentSql' => $champ->equivalentSql));
							$champ2Camp = $champsFormulaireTable->selectWith($select)->current();
							if ($champ2Camp) {
								$champ = $champ2Camp;
							}

							$where = array('idLocataire' => $idLocataire, 'idChamp' => $champ->id);
							if ($idResa) {

								## controle valeurs champ liste sur la bonne campagne
								if (is_numeric($champ->sourceListe) && $valeur) {
									$tableValSelect = $this->getTableObjet('valeurs_select');
									$select = $tableValSelect->getSql()->select();
									$select->join('champs_formulaires', 'valeurs_select.idSelect = champs_formulaires.sourceListe', array('idChamp' => 'id', 'idFormulaire', 'sourceListe'));
									$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
									$select->where(
										array(
														'formulaires.idCampagne' => $resa->idCampagne,
														'champs_formulaires.equivalentSql' => $champ->equivalentSql,
														'valeurs_select.id' => $valeur,
														)
									);
									$rowID = $tableValSelect->selectWith($select)->current();
									if (!$rowID) {
										return array('msg' => "Elément de liste Invalide(pas sur la bonne campagne)<br />");
									}
								}

								$where['idReservation'] = $idResa;

								##verification RIB-IBAN
								if ($champ->idType == 15 && $valeur) {
									$isValidRIB = $tools->checkIBAN($valeur);
									if (!$isValidRIB) {
										return array('msg' => "IBAN $valeur Invalide");
									}
								}
								##verification RIB-BIC
								if ($champ->idType == 16 && $valeur) {
									$isValidBIC = $tools->checkBIC($valeur);
									if (!$isValidBIC) {
										return array('msg' => "BIC $valeur Invalide");
									}
								}

								##verification changement champ lié à une formule
								$rep = $this->getPrestaTable()->isPrestaDynField($idResa, $champ->equivalentSql);
								if ($rep != "ok") {
									return array('msg' => $rep);
								}

								##verification changement rib
								if ($valeur && $champ->idType == 15 || $champ->idType == 16 || $champ->nomXML == 'rib_nomrib') {
									$this->checkMajStatutRIB($idResa, $champ->id, $valeur);
								}

								if ($champ->idType == 5 || $champ->idType == 12) {
									$recalculerPresta = true;// on recalcule la presta que si on modifie un champ nombre ou monétaire
								}
							}

							//on verifie si existe update sinon ajoute
							$cd = $this->getTable($table)->select($where)->current();
							if ($champStatutDoc) {
								$data = array('statutDoc' => $valeur);
							}


							if ($cd) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa colName=$colName where=".json_encode($where)." data=".json_encode($data));
								$this->getTable($table)->update($data, $where);
								if ($champStatutDoc) {
									$champStatutDocUpdated = true;
								}
							} elseif (!$champStatutDoc) {
								$data['idLocataire'] = $idLocataire;
								$data['idReservation'] = $idResa;
								$data['idChamp'] = $champ->id;
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa colName=$colName insert data=".json_encode($data));
								$this->getTable($table)->insert($data);
							}

							## on enleve le champs des champs obligatoire vide, si rempli
							if($valeur && $idResa){
								$tableChampsObligatoires = $this->getTableObjet('champs_obligatoires');
								$tableChampsObligatoires->delete(array('idResa'=>$idResa,'idChamp'=>$champ->id)); 
							}

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update usager (edition inline)";
							$log->dataBefore = $cd ? array($champ->equivalentSql => $cd->valeur) : array();
							$log->dataAfter = array($champ->equivalentSql => $valeur);
							$log->tableName = "champs_formulaires";
							$log->idReservation = $resa->id;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###

							$up = true;
						} elseif ($table == "plai_ressources") {
							$where = array('idResa' => $idResa);

							$ress = $this->getTable($table)->select($where)->current();
							if ($ress) {
								$this->getTable($table)->update($data, $where);
							} else {
								$data['idResa'] = $idResa;
								$this->getTable($table)->insert($data);
							}
							$ress = $this->getTable($table)->select($where)->current();
							//maj des depassement
							if ($ress) {
								$this->getPLAITable()->calculerEtMajDepassement($ress->id);
							}

							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($ress, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update ressources (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "plai_ressources";
							$log->idReservation = $resa->id;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###
						} elseif ($table == "prestations_to_resa" && !empty($post['idPrestation'])) {
							if ($champ->equivalentSql == 'controle1' || $champ->equivalentSql == 'controle2' || $champ->equivalentSql == 'modePaiement') {
								$where = array('idReservation' => $idResa, 'idPrestation' => $post['idPrestation']);
								if ($post['idResaPresta'] > 0) {
									$where['id'] = $post['idResaPresta'];
								}
								$update = true;
								if ($champ->equivalentSql == 'modePaiement' && $data['modePaiement'] == 'Virement') {
									//si mode Virement, on verifie si le RIB est controlé
									$msgRIB = $this->getPrestaTable()->checkStatutRIB($idResa);
									if ($msgRIB != 'ok') {
										$update = false;
										$this->messages['editionInline']['error'][] = $msgRIB;
									}
								}
								$ptr = $this->getTable($table)->select($where)->current();
								if ($ptr && $ptr->etatPrestation != 'affecte' && ($champ->equivalentSql != 'modePaiement' || $champ->equivalentSql == 'modePaiement' && $ptr->etatPrestation == 'regle')) {
									$update = false;
									$recalculerPresta = false;
									$this->messages['editionInline']['error'][] = "Modification bloquée : La prestation est en état différent d'affectée";
								}

								if ($ptr && $update) {
									$this->getTable($table)->update($data, $where);

									### save logs
									$log = new Logs();
									$diff = $log->arrayDiff($ptr, $data);
									$log->dateOperation = date('Y-m-d H:i:s');
									$log->idGestionnaire = $gestId;
									$log->operation = "BO update etat controle prestation (edition inline)";
									$log->dataBefore = $diff['before'];
									$log->dataAfter = $diff['after'];
									$log->tableName = "prestations_to_resa";
									$log->idReservation = $resa->id;
									$log->idLocataire = $resa->idLocataire;
									$this->getLogsTable()->saveLogs($log);
									###
									$htmlOP = $valeur;
								}
							}
						} elseif ($table == "prelevements_sepa") {
							$where = array('idReservation' => $idResa);

							$sepaRow = $this->getTable($table)->select($where)->current();
							if ($sepaRow) {
								$this->getTable($table)->update($data, $where);
							} else {
								$data['idReservation'] = $idResa;
								$this->getSEPATable()->save($data);
							}

							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($sepaRow, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update SEPA (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "prelevements_sepa";
							$log->idReservation = $resa->id;
							$log->idLocataire = $resa->idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###
						} elseif ($table == "choix_typelogement" && substr($champ->code, 0, -1) == 'residence') {
							$numeroChoix = str_replace('residence', '', $champ->code);
							if($numeroChoix > 0) {
								$where = array('idReservation' => $idResa, 'numeroChoix' => $numeroChoix);
								$choix = $this->getTable($table)->select($where)->current();
								if ($choix) {
									$this->getTable($table)->update($data, $where);
								} else {
									$data['idReservation'] = $idResa;
									$data['numeroChoix'] = $numeroChoix;
									$this->getTable($table)->save($data);
								}

								### save logs
								$log = new Logs();
								$diff = $log->arrayDiff($choix, $data);
								$log->dateOperation = date('Y-m-d H:i:s');
								$log->idGestionnaire = $gestId;
								$log->operation = "BO update choix résidence $numeroChoix (edition inline)";
								$log->dataBefore = $diff['before'];
								$log->dataAfter = $diff['after'];
								$log->tableName = $table;
								$log->idReservation = $resa->id;
								$log->idLocataire = $resa->idLocataire;
								$this->getLogsTable()->saveLogs($log);
							}
							###
						}
						if (property_exists($champ, 'nature') && $champ->nature == "libre") {
							if ($champStatutDoc && $champStatutDocUpdated) {
								$statutuDocRow = $this->getTableObjet('statut_docs')->select(array('id' => $valeur))->current();
								if ($statutuDocRow) {
									$htmlOP = $statutuDocRow->nom;
								} else {
									$htmlOP = "";
								}
							} else {
								$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
								$infos = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($idLocataire, $adapter, $idResa);
								if ($champ->idType == 2 && !empty($infos[$champ->equivalentSql])) {
									$infos[$champ->equivalentSql] = date('d-m-Y', strtotime($infos[$champ->equivalentSql]));
								}
								$htmlOP = !empty($infos[$champ->equivalentSql]) ? $infos[$champ->equivalentSql] : "";
							}
						} elseif(!in_array($table, array('plai_ressources', 'prestations_to_resa', 'prelevements_sepa'))) {


							//$resa = $this->getResaTable()->getListe($idResa)->current();
							$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
							$htmlOP = $resa->$champCode;
							if ($champCode == "statutAssur") {
								$statut = array('Non traitée', 'Refusée', 'Validée');
								$htmlOP = $statut[$resa->$champCode];
								if (!$resa->$champCode) {
									$htmlOP = 'Non traitée';
								}
							} elseif ($champCode == "statutRIB") {
								$statuts = array('modifier' => 'Modifié', 'controler' => 'Controlé');
								if (array_key_exists($resa->$champCode, $statuts)) {
									$htmlOP = $statuts[$resa->$champCode];
								} else {
									$htmlOP = 'Vide';
								}
							} elseif (substr($champCode, 0, 4) == "daten g" && $resa->$champCode) {
								$htmlOP = date('d-m-Y', strtotime($resa->$champCode));
							}
						}


						if ($up) {
							## MAJ bredea
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");
							$this->updateResaPmsAndSig($idResa);
						}

						## recalculation des prestation calculé
						if ($recalculerPresta) {
							$this->getPrestaTable()->calculerPrestationsDeResa($resa->id);
						}
					}
				} elseif ($idDp) {
					$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
					if ($dp) {
						$data = array($champ->equivalentSql => $valeur);
						$idLocataire = $dp->idLocataire;
						if ($table == "domiciliations") {
							$this->getTable($table)->update($data, array('id' => $idDp));
							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($dp, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update domiciliations (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "domiciliations";
							$log->idReservation = null;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###
						} elseif ($table == "locataires") {
							$where = array('id' => $idLocataire);
							$loc = $this->getTable($table)->select($where)->current();

							### save logs
							$log = new Logs();
							$diff = $log->arrayDiff($loc, $data);
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update usager (edition inline)";
							$log->dataBefore = $diff['before'];
							$log->dataAfter = $diff['after'];
							$log->tableName = "locataires";
							$log->idReservation = null;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###

							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idDp=$idDp champCode=$champCode update table=$table where=".json_encode($where)." data=".json_encode($data));
							$this->getTable($table)->update($data, $where);

							$up = true;
						} elseif ($table == "valeurs_dynamiques") {
							$data = array('valeur' => $valeur);
							$where = array('idLocataire' => $idLocataire, 'idChamp' => $champ->id);
							if ($idDp) {
								$where['idDp'] = $idDp;
							}
							//on verifie si existe update sinon ajoute
							$cd = $this->getTable($table)->select($where)->current();
							if ($cd) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idDp=$idDp colName=$colName where=".json_encode($where)." data=".json_encode($data));
								$this->getTable($table)->update($data, $where);
							} else {
								$data['idLocataire'] = $idLocataire;
								$data['idDp'] = $idDp;
								$data['idChamp'] = $champ->id;
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idDp=$idDp colName=$colName insert data=".json_encode($data));
								$this->getTable($table)->insert($data);
							}

							### save logs
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO update usager (edition inline)";
							$log->dataBefore = $cd ? array($champ->equivalentSql => $cd->valeur) : array();
							$log->dataAfter = array($champ->equivalentSql => $valeur);
							$log->tableName = "champs_formulaires";
							$log->idReservation = 0;
							$log->idLocataire = $idLocataire;
							$this->getLogsTable()->saveLogs($log);
							###

							$up = true;
						}

						if ($up) {
							$resaDeLocDp = $this->getResaTable()->getLocLastResa($idLocataire);
							if ($resaDeLocDp) {
								$this->updateResaPmsAndSig($resaDeLocDp->id);
							}
						}
					}
				}
			}
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa htmlOP=$htmlOP");
		return $htmlOP;
	}

	## chargement de la view liste/modele.phtml
	private function loadModelesMailView($params = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : params=".json_encode($params));
		$idModele = !empty($params['idModele']) ? $params['idModele'] : 0;
		$idCategorie = !empty($params['idCategorie']) ? $params['idCategorie'] : 0;
		$modeListe = !empty($params['modeListe']) ? $params['modeListe'] : "";
		$isResa = !empty($params['isResa']) ? $params['isResa'] : 0;
		$fromController = !empty($params['fromController']) ? $params['fromController'] : 'liste';
		$exportListe = !empty($params['exportListe']) ? $params['exportListe'] : '';//si on joint l export d'une liste au mail ou non
		$callType = !empty($params['callType']) ? $params['callType'] : '';//si on fait l'appel depuis la fiche usager-Document ou autres
		$typeListeFact = !empty($params['typeListeFact']) ? $params['typeListeFact'] : '';//appel depuis la liste type facture(facturesmois)

		if($typeListeFact == 'facturesmois' && !$idModele) {
			$modelesFact = $this->getModelesmailTable()->getModelesByCode('facture');
			if($modelesFact->count() > 0) {
				$modeleFact = $modelesFact->current();
				$idModele = $modeleFact->id;
			}
		}
		//on verifie si le idModele est composé : si oui c'est un modele campagne
		$idModeleCampArr = explode('-', $idModele);
		$idCampagne = $idModeleParent = 0;
		if (sizeof($idModeleCampArr) > 1) {
			$idModeleParent = $idModeleCampArr[0];
			$idCampagne = $idModeleCampArr[1];
		}
		$msg = "";
		$allowed = 0;
		$maj = 1; //maj du type et nom, interdit pour les mail auto

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
		$liensDocsPJ = array();
		if($callType == 'ficheUsagerDocs') {
			//appel depuis la fiche usager-Documents
			$mailSession = new Container('mailing');
			$mailOptions = $mailSession->mailOptions;
			if(!empty($mailOptions)) {
				$liensDocsPJ = $mailOptions['liensDocsPJ'];
				$idModele = $mailOptions['idModele'];
				//$idResa = $mailOptions->idResa;
			}
			//print_r($mailSession->mailOptions);
		}
		//envois de mail depuis le compte financier
		if($callType == 'ficheUsagerCompte') {
			$mailSession = new Container('mailing');
			$mailOptions = $mailSession->mailOptions;
			if(!empty($mailOptions)) {
				$idModele = $mailOptions['idModele'];
			}
		}

		$form = new MailForm();

		$langues = $this->getLangues();

		//liste des emails
		$result = $this->getTableObjet('email_liste')->select();
		$emails = array();
		$emailOptions = array();
		foreach ($result as $row) {
			$emails[] = $row;
			$emailOptions[$row->email] = $row->email;
		}

		$form->get('emailFrom')->setAttribute('options', $emailOptions);

		//etats de liste public,private
		$tableObj3 = new Tables('type_email', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$types = $tableObj3->getTable()->select(array('auto' => '1'));
		$types2 = $tableObj3->getTable()->select(array('auto' => '1'));
		$typesOption = array();

		//on affiche juste les deux type public et privé si nouveau modele
		if ($idModele > 0 || $idCampagne > 0) {
			if ($idCampagne > 0) {
				$modele = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
				//on recup, le idType, langue, idUser et idCategorie du modele parent
				$modeleParent = $this->getModelesmailTable()->getModele($idModeleParent);
				if ($modeleParent) {
					$modele->idType = $modeleParent->idType;
					$modele->langue = $modeleParent->langue;
					$modele->idUser = $modeleParent->idUser;
					$modele->idCategorie = $modeleParent->idCategorie;
					$modele->id = $idModeleParent.'-'.$idCampagne;
					$modele->nomModele = $modeleParent->nomModele;
				}
			} else {
				$modele = $this->getModelesmailTable()->getModele($idModele);
			}

			if ($modele->idType <= 2) {
				$modele->idType = "";
			}
			if ($modele->idType > 2) {
				foreach ($types as $t) {
					$optt = array('label' => $t->type, 'value' => $t->id,
							'attributes' => array('data-code' => $t->code));
					$typesOption[$t->id] = $optt;
				}
			} else {
				foreach ($types as $t) {
					//if($t->id <=2 ){
					$optt = array('label' => $t->type, 'value' => $t->id,
							'attributes' => array('data-code' => $t->code));
					$typesOption[$t->id] = $optt;
					//}
				}
			}
		} else {
			foreach ($types as $t) {
				if ($t->id <= 2) {
					$optt = array('label' => $t->type, 'value' => $t->id,
							'attributes' => array('data-code' => $t->code));
					$typesOption[$t->id] = $optt;
				} else {
					//on verifie si chaque type auto est dans toutes les langues
					foreach ($langues as $code => $nomLangue) {
						$md = $this->getModelesmailTable()->getModeleByTypeAndLangue($t->id, $code);
						if (!$md && $t->code != 'configurable' && $t->code != 'animation') {
							$optt = array('label' => $t->type, 'value' => $t->id,
							'attributes' => array('data-code' => $t->code));
							$typesOption[$t->id] = $optt;
						}
					}
				}
				if ($t->code == 'configurable' || $t->code == 'animation') {
					$optt = array('label' => $t->type, 'value' => $t->id,
						'attributes' => array('data-code' => $t->code));
					$typesOption[$t->id] = $optt;
				}
			}
		}


		$form->get('idType')->setAttribute('options', $typesOption);

		foreach ($types2 as $t) {
			$typesModeles[$t->id] = $t->type;
		}
		$typesModeles[1] = "Pas de type";
		$typesModeles[2] = "Pas de type";

		##campagnes destinataire pour le type configurable
		$campagnesRes = $this->getCampagneTable()->fetchAll();
		$campagnesOpt = array();
		foreach($campagnesRes as $campRow) {
			$campagnesOpt[$campRow->id] = $campRow->nom;
		}
		$form->get('idCampagneDest')->setAttribute('options', $campagnesOpt);

		##etat reservations
		$etatResas = $this->getTableObjet('etat_reservation')->select();
		$etatResasOpt = array();
		foreach($etatResas as $er) {
			$etatResasOpt[$er->id] = $er->nom;
		}
		$form->get('etatResa')->setAttribute('options', $etatResasOpt);

		/*$modelesOption = array();
		foreach($modeles as $m){
			//on affiche les listes public
			$catName = $m->categorie ? $m->categorie : 'Sans catégorie';
			$typeName = $m->idType && $typesModeles[$m->idType] != "" ? $typesModeles[$m->idType] : 'Sans type';
			$opt = array('label'=>'('.$catName.')'.$m->nomModele." (".$typeName.")", 'value'=>$m->id,
						'attributes'=>array('data-type'=>$m->idType,'data-langue'=>$m->langue)
						);
			if($m->idType != '2'){
				$modelesOption[] = $opt;
			}elseif($m->idUser == $gestId){
				$modelesOption[] = $opt;
			}
		}*/

		$modeles = $this->getModelesmailTable()->fetchAll($idProfile, $idCategorie, 'mailing');

		$modelesOption = array();
		$modelesParCat = array();
		$catModeles = array();
		foreach ($modeles as $m) {
			$idCat = $m->idCategorie ? $m->idCategorie : '-1';
			$modelesParCat[$idCat][] = $m;
			if ($idCat > 0) {
				$catModeles[$idCat] = $m->categorie;
			} else {
				$catModeles[$idCat] = 'Sans catégorie';
			}
		}
		foreach ($catModeles as $idCat => $catName) {
			$modeles = !empty($modelesParCat[$idCat]) ? $modelesParCat[$idCat] : array();
			$opt = array();
			$options = array();
			foreach ($modeles as $m) {
				if ($m->idModeleCampagne) {
					$m->id = $m->idModeleCampagne;
				}//pour les modeles de la campagne : $idModele.'-'.idCampagne

				//on affiche les listes public
				$catName = $m->categorie ? $m->categorie : 'Sans catégorie';
				$typeName = $m->idType && $typesModeles[$m->idType] != "" ? $typesModeles[$m->idType] : 'Sans type';
				$campName = $m->campagne ? ' ('.$m->campagne.')' : '';
				$opt = array('label' => $m->nomModele." (".$typeName.")".$campName, 'value' => $m->id,
							'attributes' => array('data-type' => $m->idType, 'data-langue' => $m->langue, 'data-objet' => $m->objet),
							);

				if($idModele > 0 && $idModele == $m->id) {
					$opt['selected'] = true;
				}

				if ($m->idType != '2') {
					$options[] = $opt;
				} elseif ($m->idUser == $gestId) {
					$options[] = $opt;
				}
			}
			//cas envois de mail depuis le compte financier : on laisse que le type de modèle choisi
			if($callType == "ficheUsagerCompte") {
				foreach($options as $k => $op) {
					if($op['value'] != $idModele) {
						unset($options[$k]);
					}
				}
			}
			$modelesOption[] = array('label' => $catName, 'options' => $options);
		}

		$form->get('idModele')->setAttribute('options', $modelesOption);
		$form->get('idModele')->setValue($idModele);
		if($idModele > 0 && ($callType == "ficheUsagerDocs" || $callType == "ficheUsagerCompte")) {
			$form->get('idModele')->setEmptyOption(null);
		}

		##langue
		$form->get('langue')->setAttribute('options', $langues);
		$form->get('langueFiltre')->setAttribute('options', $langues);

		## categories
		$catsRows = $this->getTableObjet('categorie_mail')->select(array('deleted' => 0));
		$catOptions = array();
		foreach ($catsRows as $row) {
			$catOptions[$row->id] = $row->categorie;
		}
		$form->get('idCategorie')->setAttribute('options', $catOptions);
		$form->get('idCategorieFiltre')->setAttribute('options', $catOptions);
		$form->get('idCategorieFiltre')->setValue($idCategorie);

		$modele = null;
		if ($idModele > 0 || $idCampagne > 0) {
			if ($idCampagne > 0) {
				$modele = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
				//on recup, le idType, langue, idUser et idCategorie du modele parent
				$modeleParent = $this->getModelesmailTable()->getModele($idModeleParent);
				if ($modeleParent) {
					$modele->idType = $modeleParent->idType;
					$modele->langue = $modeleParent->langue;
					$modele->idUser = $modeleParent->idUser;
					$modele->idCategorie = $modeleParent->idCategorie;
					$modele->id = $idModeleParent.'-'.$idCampagne;
					$modele->nomModele = $modeleParent->nomModele;
				}
			} else {
				$modele = $this->getModelesmailTable()->getModele($idModele);
			}
			if ($modele->idUser == $gestId || ($_SESSION['USERDROIT']['btn-delete-modele-mail'] == 'R' || $_SESSION['USERDROIT']['btn-delete-modele-mail'] == 'W')) {
				$allowed = 1;
			}
			//pour les mail auto
			if ($modele->idType > 2) {
				$maj = 0;
				$isResa = true;//on affiche tout les champs si mail auto
			}
			if($modele->etatResa) {
				$modele->etatResa = explode(',', $modele->etatResa);
			}
			$form->bind($modele);
		}

		## profiles
		$profilesResult = $this->getTableObjet('user_role')->select();
		$profiles = array();
		$profilesDest = array();
		$profilesCopie = array();
		$profilesCopieCachee = array();
		foreach ($profilesResult as $profile) {
			if ($profile->role_id != "guest" && $profile->role_id != "user") {
				//selected des profiles choisis
				$pRow = $this->getTableObjet('modeles_email_profile')->select(array('idModele' => $idModele, 'idProfile' => $profile->role_id))->current();
				if ($pRow) {
					$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
				} else {
					$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
				}

				// profils en tant que destinataire/copie/coie cachée
				$pRow = $this->getTableObjet('modeles_email_profile_envois')->select(array('idModele' => $idModele, 'idProfile' => $profile->role_id, 'typeEnvois' => 'dest'))->current();
				if ($pRow) {
					$profilesDest[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
				} else {
					$profilesDest[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
				}

				$pRow = $this->getTableObjet('modeles_email_profile_envois')->select(array('idModele' => $idModele, 'idProfile' => $profile->role_id, 'typeEnvois' => 'copie'))->current();
				if ($pRow) {
					$profilesCopie[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
				} else {
					$profilesCopie[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
				}

				$pRow = $this->getTableObjet('modeles_email_profile_envois')->select(array('idModele' => $idModele, 'idProfile' => $profile->role_id, 'typeEnvois' => 'copieCachee'))->current();
				if ($pRow) {
					$profilesCopieCachee[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
				} else {
					$profilesCopieCachee[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
				}


			}
		}
		$form->get('idProfile')->setAttribute('options', $profiles);
		$form->get('idProfileDest')->setAttribute('options', $profilesDest);
		$form->get('idProfileCopie')->setAttribute('options', $profilesCopie);
		$form->get('idProfileCopieCachee')->setAttribute('options', $profilesCopieCachee);

		## Export listes en PJ
		$modesListes = $this->getGlobalHelper()->getModesListes($typeAppel = 'mailing');
		$form->get('idListePJ')->setAttribute('options', $modesListes);
		if($idModele) {
			$melRows = $this->getTableObjet('modeles_email_listes')->select(array('idModele' => $idModele));
			if($melRows->count() > 0) {
				$melVals = array();
				foreach($melRows as $mel) {
					$melVals[] = $mel->modeListe.'|'.$mel->idListe;
				}
				$form->get('idListePJ')->setValue($melVals);
			}
		}

		## modèles docs
		if($idCampagne > 0){
			$modelesDocs = $this->getTableObjet('modeles_email_modeles_docs_camp')->select(array('idModeleMail' => $idModele,'idCampagne'=>$idCampagne));
		}else{
			$modelesDocs = $this->getTableObjet('modeles_email_modeles_docs')->select(array('idModeleMail' => $idModele));
		}
		
		$idsModelesDocs = '';
		if ($modelesDocs->count() > 0) {
			$idsModelesDocsArr = array();
			foreach ($modelesDocs as $md) {
				$idsModelesDocsArr[$md->idModeleDoc] = $md->idModeleDoc;
			}
			$idsModelesDocs = implode('-', $idsModelesDocsArr);
		}

		## remplir la liste des utilisateurs
		$usersResult = $this->getTableObjet('user')->select(array('deleted' => '0'));
		$usersOption = array();
		foreach ($usersResult as $u) {
			$usersOption[] = array('value' => $u->user_id,
									'label' => $u->display_name,
									'attributes' => array('data-email' => $u->email),
									);
		}
		$form->get('idUtilisateur')->setAttribute('options', $usersOption);

		## Type suivis animation pour le modèle animation
		$typesSuivis = $this->getSuivisTable()->getTypesSuivisByCode(array('animation', 'participation'));
		$form->get('idTypeSuivis')->setAttribute('options', $typesSuivis);

		## Catalogue animation pour le modèle animation
		$typesCatalogue = $this->getCatalogueTable()->getListeTypesCatalogueParType('animation');
		$cataOpt = array();
		foreach($typesCatalogue as $idTypeCatalogue => $typeCatalogue) {
			$options = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue, array('gestId' => $gestId));
			if(!empty($options)) {
				foreach($options as $idOpt => $valOpt) {
					$cataOpt[$idOpt] = $valOpt;
				}
			}
		}
		$form->get('idCatalogue')->setAttribute('options', $cataOpt);

		if($idModele) {
			$mdRow = $this->getTableObjet('modeles_email_animation')->select(array('idModele' => $idModele))->current();
			if($mdRow) {
				if($mdRow->idTypeSuivis) {
					$form->get('idTypeSuivis')->setValue($mdRow->idTypeSuivis);
				}
				if($mdRow->idCatalogue) {
					$form->get('idCatalogue')->setValue($mdRow->idCatalogue);
				}
			}
		}

		extract($this->getModeleMailChamps($params));

		$conf = $this->getConfigurationTable()->getConfig(1);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/modele')
		->setVariables(array(
				'id' => $idModele,
				'form' => $form,
				'msg' => $msg,
				'modele' => $modele,
				'isResa' => $isResa,
				//'theme1' => $this->getThemeFields(1),
				//'theme2' => $this->getThemeFields(2),
				//'theme3' => $this->getThemeFields(3),
				//'theme4' => $this->getThemeFields(4),
				'emails' => $emails,
				//'theme5' => $this->getDynamiqueFields(),
				'docsTable' => $this->getDocumentTable(),
				'written' => ($_SESSION['USERDROIT']['mode-input-mails'] == 'W'),
				'modeListe' => $modeListe,
				'catRows' => $catRows,
				'allChamps' => $allChamps,
				//'lstLoc'=>implode(',',$listMailing),
				'idCampagne' => $idCampagne,
				'exportListe' => $exportListe,
				'idsModelesDocs' => $idsModelesDocs,
				'catsDeBase' => $catsDeBase,
				'conf' => $conf,
				'callType' => $callType,
				'liensDocsPJ' => $liensDocsPJ,

		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return array('htmlOutput' => $htmlOutput, 'maj' => $maj, 'allowed' => $allowed, 'idCampagne' => $idCampagne, 'idModele' => $idModele);
	}

	public function modeleAction()
	{
		##$form = new MailForm();
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$msg = "";
		$allowed = 0;
		$maj = 1; //maj du type et nom, interdit pour les mail auto

		if ($request->isXmlHttpRequest()) {
			/*$gestId = 1;
			if( $auth->hasIdentity() ){
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;*/

			$idModele = $request->getPost('id');
			$isResa = (int) $request->getPost('isResa');
			$idCategorie = (int) $request->getPost('idCategorie');
			$modeListe = $request->getPost('modeListe');
			$fromController = $request->getPost('fromController');
			$exportListe = $request->getPost('exportListe', '');
			$callType = $request->getPost('callType', '');
			$typeListeFact = $request->getPost('typeListeFact', '');//Mode facture(facturesmois)pour charger le modèle facture par défaut


			$params = array('idModele' => $idModele, 'idCategorie' => $idCategorie, 'modeListe' => $modeListe, 'isResa' => $isResa, 'fromController' => $fromController, 'exportListe' => $exportListe, 'callType' => $callType, 'typeListeFact' => $typeListeFact);
			extract($this->loadModelesMailView($params));
			//$listMailing = $request->getPost('listeMailing');

			//$sess = new Container("mailingList");
			//$sess->listMailing = $listMailing;

			/*****
			$langues = $this->getLangues();

			//liste des emails
			$result = $this->getTableObjet('email_liste')->select();
			$emails = array();
			$emailOptions = array();
			foreach($result as $row){
				$emails[] = $row;
				$emailOptions[$row->email] = $row->email;
			}

			$form->get('emailFrom')->setAttribute('options',$emailOptions);

			//etats de liste public,private
			$tableObj3 = new Tables('type_email',$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$types = $tableObj3->getTable()->select(array('auto'=>'1'));
			$types2 = $tableObj3->getTable()->select(array('auto'=>'1'));
			$typesOption = array();

			//on affiche juste les deux type public et privé si nouveau modele
			if($idModele > 0){
				$modele = $this->getModelesmailTable()->getModele($idModele);
				if($modele->idType <= 2){
					$modele->idType = "";
				}
				if($modele->idType > 2){
					foreach($types as $t){
						$typesOption[$t->id] = $t->type;
					}
				}else{
					foreach($types as $t){
						//if($t->id <=2 ){
							$typesOption[$t->id] = $t->type;
						//}
					}
				}
			}else{
				foreach($types as $t){

					if($t->id <=2 ){
						$typesOption[$t->id] = $t->type;
					}else{
						//on verifie si chaque type auto est dans toutes les langues
						foreach ($langues as $code => $nomLangue) {
							$md = $this->getModelesmailTable()->getModeleByTypeAndLangue($t->id,$code);
							if(!$md){
								$typesOption[$t->id] = $t->type;
							}
						}
					}
				}
			}


			$form->get('idType')->setAttribute('options',$typesOption);

			foreach($types2 as $t){
				$typesModeles[$t->id] = $t->type;
			}
			$typesModeles[1] = "Pas de type";
			$typesModeles[2] = "Pas de type";

			$modeles = $this->getModelesmailTable()->fetchAll($idProfile,$idCategorie);
			$modelesOption = array();
			foreach($modeles as $m){
				//on affiche les listes public
				$catName = $m->categorie ? $m->categorie : 'Sans catégorie';
				$typeName = $m->idType && $typesModeles[$m->idType] != "" ? $typesModeles[$m->idType] : 'Sans type';
				$opt = array('label'=>'('.$catName.')'.$m->nomModele." (".$typeName.")", 'value'=>$m->id,
							'attributes'=>array('data-type'=>$m->idType,'data-langue'=>$m->langue)
							);
				if($m->idType != '2'){
					$modelesOption[] = $opt;
				}elseif($m->idUser == $gestId){
					$modelesOption[] = $opt;
				}
			}

			$form->get('idModele')->setAttribute('options',$modelesOption);
			$form->get('idModele')->setValue($idModele);

			##langue
			$form->get('langue')->setAttribute('options',$langues);
			$form->get('langueFiltre')->setAttribute('options',$langues);

			## categories
			$catsRows = $this->getTableObjet('categorie_mail')->select(array('deleted'=>0));
			$catOptions = array();
			foreach($catsRows as $row){
				$catOptions[$row->id] = $row->categorie;
			}
			$form->get('idCategorie')->setAttribute('options',$catOptions);
			$form->get('idCategorieFiltre')->setAttribute('options',$catOptions);
			$form->get('idCategorieFiltre')->setValue($idCategorie);

			$modele = null;
			if($idModele > 0){
				$modele = $this->getModelesmailTable()->getModele($idModele);
				if($modele->idUser == $gestId && $modele->idListe != 0){
					$allowed = 1;
				}
				//pour les mail auto
				if($modele->idType > 2){
					$maj = 0;
					$isResa = true;//on affiche tout les champs si mail auto
				}
				$form->bind($modele);
			}

			## profiles
			$profilesResult = $this->getTableObjet('user_role')->select();
			$profiles = array();
			foreach($profilesResult as $profile){
				if($profile->role_id != "guest"){
					//selected des profiles choisis
					$pRow = $this->getTableObjet('modeles_email_profile')->select(array('idModele'=>$idModele,'idProfile'=>$profile->role_id))->current();
					if($pRow){
						$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
					}else{
						$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
					}
				}
			}
			$form->get('idProfile')->setAttribute('options',$profiles);

			extract($this->getModeleMailChamps());

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modele')
			->setVariables(array(
					'id' => $idModele,
					'form' => $form,
					'msg' => $msg,
					'modele' => $modele,
					'isResa' => $isResa,
					//'theme1' => $this->getThemeFields(1),
					//'theme2' => $this->getThemeFields(2),
					//'theme3' => $this->getThemeFields(3),
					//'theme4' => $this->getThemeFields(4),
					'emails'=>$emails,
					//'theme5' => $this->getDynamiqueFields(),
					'docsTable'=>$this->getDocumentTable(),
					'written'=>($_SESSION['USERDROIT']['mode-input-mails'] == 'W'),
					'modeListe'=>$modeListe,
					'catRows' => $catRows,
					'allChamps' => $allChamps,
					//'lstLoc'=>implode(',',$listMailing),

			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			*/
			$idTypeMail = $request->getPost('type');
			$pametres_mail = null;
			if($idTypeMail > 2) {
				$pametres_mail = $this->getTableObjet('pametres_mail')->select(array('idTypeEmail' => $idTypeMail))->current();
			}
			if ($idModele) {
				$pametres_mail_modele = $this->getTableObjet('pametres_mail')->select(array('idModele' => $idModele))->current();
				if ($pametres_mail_modele) {
					$pametres_mail = $pametres_mail_modele;
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						'id' => $idModele,
						'allowed' => $allowed,
						'maj' => $maj,
						  'htmlOP' => $htmlOutput,
						  'idCampagne' => $idCampagne,
						  'pametres_mail' => $pametres_mail,

			));

			$view->setTerminal(true);
			return $view;
		}
	}



	public function checkmodelelangueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idType = $request->getPost('idType');
			$optHtml = "";
			if ($idType > 2) {
				$type = $this->getTableObjet('type_email')->select(array('id' => $idType))->current();
				$codeType = $type ? $type->code : null;
				$langues = $this->getLangues();
				foreach ($langues as $code => $nomLangue) {
					$md = $this->getModelesmailTable()->getModeleByTypeAndLangue($idType, $code);
					if (!$md || $codeType == 'configurable' || $codeType == 'animation') {
						//ok
						$optHtml .= '<option value="'.$code.'">'.$nomLangue.'</option>';
					} else {
						//disable
						$optHtml .= '<option disabled="disabled" value="'.$code.'">'.$nomLangue.'</option>';
					}
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						'optHtml' => $optHtml,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadConfigMailAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idModele = $request->getPost('idModele', 0);
			$idCampagne = $request->getPost('idCampagne', 0);

			$htmlOP = $this->loadModeleMailConfig($idModele, $idCampagne);

			$view = new JsonModel(array(
						'success' => true,
						'idModele' => $idModele,
						'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}
	private function loadModeleMailConfig($idModele, $idCampagne)
	{
		$tools = new Tools();
		$tableCF = $this->getTable('champs_formulaires');
		$tableMMC = $this->getTable('modeles_email_conditions');

		//on cherche les champs type date
		$champs = array();

		$select = $tableCF->getSql()->select();
		$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne', 'formulaire' => 'nom'));
		$select->where(array('formulaires.idCampagne' => $idCampagne, 'champs_formulaires.active' => 1, 'champs_formulaires.idType' => 2));
		$cRows = $tableCF->selectWith($select);
		foreach($cRows as $champ) {
			$champs[$champ->id] = $champ;
		}

		$champDO = new \stdClass();
		$champDO->equivalentSql = 'dateOption';
		$champDO->id = -3;
		$champ->idType = 2;
		$champDO->libelle = 'Date affectation(option)';
		$champs[-3] = $champDO;

		$champDO = new \stdClass();
		$champDO->equivalentSql = 'dateDemandeReservation';
		$champDO->id = -4;
		$champ->idType = 2;
		$champDO->libelle = 'Date demande réservation';
		$champs[-4] = $champDO;

		$champDO = new \stdClass();
		$champDO->equivalentSql = 'dateConfirmation';
		$champDO->id = -5;
		$champ->idType = 2;
		$champDO->libelle = 'Date confirmation';
		$champs[-5] = $champDO;

		$champsFixe = array(-3, -4, -5);

		$criteres = $this->getModelesMailConditionsTable()->getRowsBy(array('idModele' => $idModele));


		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/configmails')
		->setVariables(array(
			'champs' => $champs,
			'idModele' => $idModele,
			'idCampagne' => $idCampagne,
			'criteres' => $criteres,
			'champsFormTable' => $this->getTableObjet('champs_formulaires'),
			'operateurs' => $tools->getOperateurs(),
			'champsFixe' => $champsFixe,
		));

		$htmlOP = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);
		return $htmlOP;
	}

	public function saveConfigMailAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$post = $request->getPost();
			$idModele = $request->getPost('idModele', 0);
			$idCampagne = $request->getPost('idCampagne', 0);

			$postVarsToBdd = array(
									'champCritere1' => 'idChamp',
									'operateur' => 'operateur',
									'champDebut' => 'champDebut',
									'champFin' => 'champFin',
									'champCritere2' => 'idChamp2',
									'valeursDate' => 'valeurExact',
									'valeursDateMin' => 'valeurMin',
									'valeursDateMax' => 'valeurMax',
									'valeursDuree' => 'valeurExact',
									'uniteExact' => 'unite',
									'valeursDureeMin' => 'valeurMin',
									'valeursDureeMax' => 'valeurMax',
									'uniteInterval' => 'unite',
									'idModele' => 'idModele',
								);
			$data = array();
			foreach($post as $var => $val) {
				if(array_key_exists($var, $postVarsToBdd)) {
					$champBdd = $postVarsToBdd[$var];
					$data[$champBdd] = $val;
				}
			}
			$typeValeur = "exact";
			if($data['operateur'] == 4) {
				$typeValeur = "interval";
			}
			$data['typeValeur'] = $typeValeur;
			//print_r($data);exit();
			if(!empty($data)) {
				$this->getModelesMailConditionsTable()->save($data);
			}

			$htmlOP = $this->loadModeleMailConfig($idModele, $idCampagne);

			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOP,
				));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function deleteConfigMailAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$id = $request->getPost('id', 0);
			$idModele = $request->getPost('idModele', 0);
			$idCampagne = $request->getPost('idCampagne', 0);
			$success = false;
			if($id) {
				$success = true;
				$this->getModelesMailConditionsTable()->delete($id);
			}
			$htmlOP = $this->loadModeleMailConfig($idModele, $idCampagne);

			$view = new JsonModel(array(
						'success' => $success,
						'htmlOP' => $htmlOP,
				));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	public function getModelesMailConditionsTable()
	{
		if (!$this->modelesMailConditionsTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->modelesMailConditionsTable = new ModelesMailConditionsTable($adapter);
		}
		return $this->modelesMailConditionsTable;
	}
	public function loadmodepushAction()
	{
		$tools = new Tools();
		return $this->forward()->dispatch('Reservation\Controller\Push', array('action' => 'loadModePush'));
	}
	public function loadmodemailAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$arrayVar = [];
			$residenceResult = $this->getResidencesTable()->fetchByGest($gestId);
			$residences = array();
			foreach ($residenceResult as $resid) {
				$residences[$resid->id] = $resid;
			}
			$batiments = array();
			if ($request->getPost('filter')) {
				$dateDebut = $request->getPost('dateDebut');
				$dateFin = $request->getPost('dateFin');
				$nomLocataire = $request->getPost('nomLocataire', '');
				$prenomLocataire = $request->getPost('prenomLocataire', '');
				$numeroChambre = $request->getPost('numeroChambre', '');
				$idsResidence = $request->getPost('idResidence', null);
				$idsBatiment = $request->getPost('idBatiment', null);

				$where = [];
				$filters = array('order' => 'id DESC');
				if ($dateDebut) {
					$where[] = '`dateEnvoi` >= "'.date('Y-m-d H:i:s', strtotime($dateDebut)).'"';
				}
				if ($dateFin) {
					$where[] = '`dateEnvoi` <= "'.date('Y-m-d H:i:s', strtotime($dateFin)).'"';
				}
				$tables = array();
				if ($nomLocataire) {
					$where[] = "locataires.nom LIKE '%$nomLocataire%'";
					$tables[] = 'locataires';
				}
				if ($prenomLocataire) {
					$where[] = "locataires.prenom LIKE '%$prenomLocataire%'";
					$tables[] = 'locataires';
				}
				if ($numeroChambre) {
					$where[] = "reservations.numeroChambre LIKE '%$numeroChambre%'";
					$tables[] = 'reservations';
				}
				if (!empty($idsBatiment)) {
					$where[] = "batiments.id IN (".implode(',', $idsBatiment).")";
					$tables[] = 'batiments';
				}
				if (!empty($idsResidence)) {
					$where[] = "batiments.idResidence IN (".implode(',', $idsResidence).")";
					$tables[] = 'batiments';
				} else {
					## Si pas de résidence choisie, ne prendre que l'historique des résidences autorisées pour le gestionnaire
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					//$where[] = "batiments.idResidence IN (".implode(',',array_keys($residences)).")";
					$subQuery1 = "IF(reservations.residenceOrientation > 0,reservations.residenceOrientation IN (".implode(',', array_keys($residences))."),1=1 )";
					array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',', array_keys($residences))."),$subQuery1 )");
					$tables[] = 'batiments';
				}
				$filters['tables'] = $tables;
				if (empty($where)) {
					$filters['limit'] = 1000;
				}
				$resultMail = $this->getHistoriquemailTable()->fetchAll($filters, $where);
				$mails = array();
				foreach ($resultMail as $row) {
					$mails[] = $row;
				}

				//chargement des batiments par residences
				if (!empty($idsResidence)) {
					$batimentResult = $this->getBatimentTable()->getBatimentsDeResidence($idsResidence);
					foreach ($batimentResult as $r) {
						$batiments[$r->id] = $r;
					}
				}

				$arrayVar = ['mails' => $mails,
							'locTable' => $this->getLocatairesTable(),
							'dateDebut' => $dateDebut,
							'dateFin' => $dateFin,
							'nomLocataire' => $nomLocataire,
							'prenomLocataire' => $prenomLocataire,
							'numeroChambre' => $numeroChambre,
							'residences' => $residences,
							'batiments' => $batiments,
							'idsResidence' => $idsResidence,
							'idsBatiment' => $idsBatiment,
							];
			} else {
				$arrayVar['residences'] = $residences;
				$arrayVar['batiments'] = $batiments;
			}

			$arrayVar['config'] = $this->getConfigurationTable()->getConfig(1);
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modemail')
			->setVariables($arrayVar);

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	## mode de liste SMS
	public function loadmodesmsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$arrayVar = [];
			if ($request->getPost('filter')) {
				$dateDebut = $request->getPost('dateDebut');
				$dateFin = $request->getPost('dateFin');
				$where = [];
				$filters = array('order' => 'id DESC');
				if ($dateDebut) {
					$where[] = '`dateEnvoi` >= "'.date('Y-m-d H:i:s', strtotime($dateDebut)).'"';
				}
				if ($dateFin) {
					$where[] = '`dateEnvoi` <= "'.date('Y-m-d H:i:s', strtotime($dateFin)).'"';
				}
				if (empty($where)) {
					$filters['limit'] = 1000;
				}
				$result = $this->getHistoriqueSMSTable()->fetchAll($filters, $where);
				$rows = array();
				foreach ($result as $row) {
					$rows[] = $row;
				}

				$arrayVar = ['rows' => $rows, 'locTable' => $this->getLocatairesTable(), 'dateDebut' => $dateDebut, 'dateFin' => $dateFin];
			}

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modesms')
			->setVariables($arrayVar);

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadmodeAlertction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			if ($request->getPost('filter')) {
				return new JsonModel(array('data' => arrray()));
			}

			$edls = $this->getEdlTable()->fetchAll()->toArray();
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modealert')
			->setVariables(array());

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array('success' => true, 'htmlOP' => $htmlOutput));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadDomiciliationsState($idListe)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe");
		$dpStateArr	= array();
		$dpStateObj	= $this->getTableObjet('domiciliations_state')->select(array('idListe' => $idListe))->current();

		// var_dump($idListe);
		// var_dump($dpStateObj);die();

		if ($dpStateObj) {
			$dpState	= json_decode($dpStateObj->data, 1);
			$configFilters = array();
			if ($dpStateObj->configFilters) {
				$configFilters = json_decode($dpStateObj->configFilters, 1);
			}
			if ($dpState && array_key_exists('filter', $dpState)) {
				if (!empty($configFilters) && $conf->filtresDyn == 1) {
					$dpStateArr = $this->getConfigFiltersTable()->reGenerateListeState($dpState, $configFilters);
				} else {
					$dpStateArr	= $dpState;
				}
			} else {
				## Peut-être l'ancien format
				## ~~~~~~~~~~~~~~~~~~~~~~~~~

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe oldFormat");
				$dpStateArr['filter']	= array();

				$champs	= array();
				$champsListe = $this->getListesTable()->getListAllFields($idListe, 'dp', $adapter);
				if ($champsListe) {
					$typeSelects	= array("1" => "text", "2" => "date", "3" => "select", "5" => "number", "6" => "text");
					foreach ($champsListe as $champ) {
						#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe codeBase=$champ[codeBase] codeDyn=$champ[codeDyn]");
						if ($champ['codeBase']) { // codeBase est égal au champ 'code' de la table champs
							## Lecture du champ de base
							## ~~~~~~~~~~~~~~~~~~~~~~~~
							$r = $this->getListesTable()->getListeField($idListe, $champ['codeBase'], 'dp', $adapter)->current();

							$typeSearch	= array_key_exists($r->idType, $typeSelects) ? $typeSelects[$r->idType] : 'text';
							$dpStateArr['filter'][$r->code]	= array("search" => "", "type" => $typeSearch);
						} elseif ($champ['codeDyn']) { // codeBase est égal au champ 'code' de la table champs
							$r = $this->getListesTable()->getListeDynamiqueField($idListe, $champ['codeDyn'], 'dp')->current();

							$typeSearch	= $typeSelects[$r->idType];
							$dpStateArr['filter'][$r->code]	= array("search" => "", "type" => $typeSearch);
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe oldFormat jsonResa=".json_encode($dpStateArr));
			}
		}
		return	$dpStateArr;
	}

	public function loadmodeDpAction()
	{
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}

			$tableC = new Tables('configuration', $adapter);
			$params = $tableC->getTable()->select()->current();

			## Lecture des paramètres
			## ~~~~~~~~~~~~~~~~~~~~~~
			$idListe = (int) $request->getPost('id');
			$limit = (int) $request->getPost('limit');
			$idCss = $request->getPost('idCss');
			$searchName = $request->getPost('searchName', '');
			$searchPrenom = $request->getPost('searchPrenom', '');
			$rechercheStricteNom = $request->getPost('rechercheStricteNom', '');
			$rechercheStrictePrenom = $request->getPost('rechercheStrictePrenom', '');
			$rechercheStricteDateNaissance = $request->getPost('rechercheStricteDateNaissance', '');
			$rechercheStricteArchive = $request->getPost('rechercheStricteArchive', '');

			if (empty($limit) || $limit < 0 || $limit > 500) {
				$limit = 500;
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : isPlanning=$isPlanning idListe=$idListe limit=$limit searchName=$searchName Version serverSide");

			## filtre bandeau
			$sessFB = new Container('filtreBandeau');
			$FiltresBandeau = isset($sessFB->filtres) ? $sessFB->filtres : array();

			$champs = array();
			$ids = array();

			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			// récuperation des listes par profile utilisateur connecté
			$allListes = $this->getListesDpByProfile($idProfile);
			$allowedListe = array();
			foreach ($allListes as $liste) {
				//on affiche les listes public
				if ($liste->idEtat == '2') {
					$allowedListe[] = $liste;
				} elseif ($liste->idUser == $gestId) {
					$allowedListe[] = $liste;
				}
			}

			$liste = array();
			// var_dump($idListe);die();
			$typeListeObj = null;
			if ($idListe > 0) {
				$listeDp = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				if ($listeDp) {
					$liste['id'] = $listeDp->id;
					$liste['nom'] = $listeDp->nom;
					$liste['idEtat'] = $listeDp->idEtat;
					$liste['idType'] = $listeDp->idType;
					$liste['stats'] = $listeDp->stats;
					if ($_SESSION['USERDROIT']['liste-input-mode-liste-btn-delete-any'] == 'R') {
						## Lorsque le profil permet de supprimer n'importe quelle liste
						$liste['canDelete'] = '1';
					} else {
						if ($listeDp->idUser == $gestId) {
							//il a le droit de supprimer
							$liste['canDelete'] = '1';
						} else {
							$liste['canDelete'] = '0';
						}
					}

					$typeListeObj = $this->getTableObjet('type_domiciliations')->select(array('id' => $liste->idType))->current();
				}
				$typeListe	= $liste['idType'];
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe liste=".json_encode($liste));

				// Récupération depuis la BDD de l'état de la liste
				$jsonDpDatatableState = $this->loadDomiciliationsState($idListe);

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe jsonDpDatatableState($jsonResaDatatableFrom)=".json_encode($jsonDpDatatableState));
				$jsonDpDatatableFilter        = $jsonDpDatatableState['filter'];
				$jsonDpDatatableFilter['code'] = 'dp';


				## Valeurs uniques pour les différents selects
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$selectOptions	= array();

				## Constitution d'une liste des lignes
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$rowsAll	= array();

				if ($jsonDpDatatableFilter) {
					$formFields = $this->getDpFields($idListe, $jsonDpDatatableFilter);
					// $formFields['dpFields']['nomLocataire']['checked'] = true;
					// $formFields['dpFields']['prenomLocataire']['checked'] = true;
					// $formFields['dpFields']['dateEntree']['checked'] = true;
					// $formFields['dpFields']['dateSortie']['checked'] = true;
					// $formFields['dpFields']['etat']['checked'] = true;

					## Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$listeChampsAffiches    = $this->getlisteChampsAffiches($jsonDpDatatableFilter, $formFields, 'dp');
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffiches));

					// Colones de la liste
					// unset($formFieldsLoc['resaFields']);
					// unset($formFieldsLoc['demFields']);
					// unset($formFieldsLoc['dynFields']);


					// $formFieldsLoc['dynFields']['code']['checked'] = false;
					// $formFields['locFields']['dateNaissance']['checked'] = true;

					$formFields['dpFields']['code']->checked = false;
					// Version rapide de la lecture de la BDD
					$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
					$where = array();

					## on charge cette partie que si on a des champs de type select
					$listeChampsAffichesSelect = array();
					$champExplicites = array();

					foreach ($listeChampsAffiches as $n => $attrs) {
						if ($attrs['idTypeHtml'] == 3 || $attrs['idTypeHtml'] == 18) {
							$listeChampsAffichesSelect[$n] = $attrs;
						}
						if (in_array($n, array('idDp', 'idLocataire'))) {
							$champExplicites[$n] = $attrs;
						}
					}

					$campagnesDeGest = [];
					## on vérifie si on a le droit d'attribution campagne, si oui on controle les campagnes sinon on affiche tout
					if($_SESSION['USERDROIT']['user-campagnes'] == 'W'){
						$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
						foreach ($gestionnaire_campagnes as $row) {
							$campagnesDeGest[] = $row->idCampagne;
						}
					}
					if (empty($campagnesDeGest)) {
						$campagnesDeGest[] = -1;
					}

					array_push($where, "IF(domiciliations.idCampagne > 0,domiciliations.idCampagne IN (".implode(',', $campagnesDeGest)."),1=1 )");

					$rowsAll = array();
					if (!empty($listeChampsAffichesSelect)) {
						$champsToRequete = array_merge($listeChampsAffichesSelect, $champExplicites);
						$rowsAll = $this->getAllDpFields($adapter, $typeListeObj, $champsToRequete, $where, array('config' => $conf, 'typeChargement' => 'header'));
					}
					// echo "<pre>";
					// print_r($formFields);
					// echo "</pre>";
					// die();

					// Constitution de la liste des options
					if ($rowsAll) {
						foreach ($rowsAll as $_key => $_row) {
							foreach ($_row as $_colName => $_value) {
								if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
									$_options	= $selectOptions[$_colName];
									if (trim($_value == "")) {
										$_value = 'null';
									}
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
									$_options	= $selectOptions[$_colName];
									if (trim($_value == "")) {
										$_value = 'null';
										$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
										if (!$_options || !in_array($_value, $_options)) {
											$selectOptions[$_colName][] = $_value;
										}
									} elseif($_value) {
										$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
										if(!empty($valsArr)) {
											foreach($valsArr as $k => $v) {
												$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
												if (!$_options || !in_array($v, $_options)) {
													$selectOptions[$_colName][] = $v;
												}
											}
										}
									}

								}
							}
						}
					}

					// Tri de ces options dans l'ordre alphabétique
					// echo "<pre>";
					// print_r($rowsAll);
					// echo "</pre>";
					// die();

					foreach ($selectOptions as $_colName => $_options) {
						sort($selectOptions[$_colName], SORT_STRING);
					}
				}

				$champsNonModifiables = array('idDp', 'idLocataire', 'nomLocataire', 'prenomLocataire');

				$modeles = array();
				$modelesRows = $this->getTableObjet('type_modeles_docs')->select(array('active' => 1, 'imprimableEnLot' => 1));
				foreach ($modelesRows as $mod) {
					$modeles[] = $mod;
				}

				// si la liste est de type stats, récupérer les modèles qui lui sont attribués
				$modelesStats = array();
				if ($liste['stats'] == '1') {
					$modelesListes = $this->getTableObjet('stats_modeles_liste')->select(array('idListe' => $idListe, 'tableListes' => 'dp_listes'))->toArray();
					if (count($modelesListes) > 0) {
						foreach ($modelesListes as $key => $modeleListe) {
							$mo = $this->getTableObjet('stats_modeles')->select(array('id' => $modeleListe['idModele']))->current();
							$modelesStats[] = $mo;
						}
					}
				}

				$htmlViewPart = new ViewModel();
				$htmlViewPart
					->setTerminal(true)
					->setTemplate('reservation/liste/modedp')
					->setVariables(array(
						'rows' 		=> array(),
						'locFields' 	=> isset($formFieldsLoc) ? $formFieldsLoc['locFields'] : [],
						'dpFields' 	=> isset($formFields) ? $formFields['dpFields'] : [],
						'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
						'i'				=> 1,
						'jsonDpDatatableState' => $jsonDpDatatableState,
						'selectOptions'	=> $selectOptions,
						'idListe'	=> $idListe ? $idListe : null,
						'typeListe'	=> $typeListe ? $typeListe : null,
						'config' => $conf,
						'searchName' => $searchName,
						'searchPrenom' => $searchPrenom,
						'rechercheStricteNom' => $rechercheStricteNom,
						'rechercheStrictePrenom' => $rechercheStrictePrenom,
						'rechercheStricteDateNaissance' => $rechercheStricteDateNaissance,
						'rechercheStricteArchive' => $rechercheStricteArchive,
						'champsNonModifiables'	=> $champsNonModifiables,
						'modeles' => $modeles,
						'listes' => $allowedListe,
						'modelesStats' => $modelesStats,
						'liste' => $liste,
					));

				$htmlOutput = $this->getServiceLocator()
						->get('viewrenderer')
						->render($htmlViewPart);

				$view = new JsonModel(array(
					'success' => true,
					'champs' => $listeChampsAffiches,
					'liste' => $liste,
					'htmlOP' => $htmlOutput,
					));
				$view->setTerminal(true);
				return $view;
			}
		}
	}

	public function afficherIndexDpAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$typesListe = array();
			$tl = $this->getTableObjet('type_domiciliations')->select();
			foreach ($tl as $t) {
				$typesListe[$t->id] = $t->type;
			}
			$allowedListe = array();
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			// récuperation des listes par profile utilisateur connecté
			$allListes = $this->getListesDpByProfile($idProfile);
			$allowedListe = array();
			foreach ($allListes as $liste) {
				//on affiche les listes public
				if ($liste->idType && array_key_exists($liste->idType, $typesListe)) {
					$liste->nom .= " (".$typesListe[$liste->idType].")";
				}
				if ($liste->idEtat == '2') {
					$allowedListe[$liste->id] = $liste;
				} elseif ($liste->idUser == $gestId) {
					$allowedListe[$liste->id] = $liste;
				}
			}

			## on y ajoute les liste privée
			$privateListes = $this->getListesTable()->fetchAllPrivate($gestId, 'dp', $adapter);
			if ($privateListes) {
				foreach ($privateListes as $liste) {
					$l = (object)$liste;
					if ($l->idType && array_key_exists($l->idType, $typesListe)) {
						$l->nom .= " (".$typesListe[$l->idType].")";
					}
					$allowedListe[$l->id] = $l;
				}
			}

			# lien campagnes création nouveau dossier
			$campagnesUserCoLiens = [];
			$campModeTable = $this->getTableObjet('modes_campagne');
			$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
			foreach ($gestionnaire_campagnes as $gestionnaire_campagne) {
				$campagne = $this->getTableObjet('campagnes')->select(array('id' => $gestionnaire_campagne->idCampagne))->current();
				if ($campagne->archive == '1') {
					continue;
				}

				$select = $campModeTable->getSql()->select();
				$select->join('campagnes', 'modes_campagne.idCampagne = campagnes.id', array('idCamp'=>'id'));
				$select->join('campagnes_type', 'campagnes_type.id = campagnes.type', array('idTypeCamp'=>'id'));
				$select->where(array('idCampagne' => $campagne->id, 'idMode' => '2','campagnes_type.code'=>'dp'));
				$modeCampagne = $campModeTable->selectWith($select)->current();

				if ($modeCampagne) {
					$campagneUserCo = (object) array();
					$campagneUserCo->nom = $campagne->nom;
					$campagneUserCo->urlAcces = $modeCampagne->urlAcces;
					$campagnesUserCoLiens[] = $campagneUserCo;
				}
			}

			// syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe typeListe=$typeListe intercontrats=".json_encode($intercontrats));
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/indexdp')
				->setVariables(array(
					'listes' => $allowedListe,
					'typesSuivis' => $this->getListeTypesSuivis(),
					'categoriesListesDp' => $this->getListesTable()->getCategoriesListe($adapter, 'dp'),
					'campagnesUserCoLiens' => $campagnesUserCoLiens,
				));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : apres htmlViewPart");

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

			$view = new JsonModel(array(
				'liste' => $liste,
				'htmlOP' => $htmlOutput,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function getListesDpByProfile($idProfile)
	{
		$table = $this->getTableObjet('domiciliations_listes');
		$select = $table->getSql()->select();
		$select->join('domiciliations_liste_profile', 'domiciliations_listes.id = domiciliations_liste_profile.idListe', [], 'left');
		$select->join('type_domiciliations', 'domiciliations_listes.idType = type_domiciliations.id', array('idT' => 'id', 'type'), 'left');
		$select->where(array('domiciliations_listes.deleted' => '0', 'domiciliations_liste_profile.idProfile' => $idProfile));
		$select->order(array('domiciliations_listes.nom ASC'));
		$resultSet = $table->selectWith($select);
		return $resultSet;
	}

	private function getAllDpFields($adapter = null, $typeListeObj = null, $champs = array(), $where = array(), $options = array())
	{
		//deplacer vers DmociliationsTable.php
		$rows = $this->getDomiciliationsTable()->getAllDpFields($adapter, $typeListeObj, $champs, $where, $options);
		return $rows;
	}

	public function getTypeListeAction()
	{
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$mode = $request->getPost('mode');
			if ($mode == 'courriers') {
				$typeListeDp = $this->getTableObjet('type_domiciliations')->select()->toArray();

				return new JsonModel(array('typeListe' => $typeListeDp));
			}
		}
	}

	## Set le libelle d'un champ pour une liste en particulier
	public function setLibelleChampListeAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($request->isXmlHttpRequest()) {
			$nameChamp = $request->getPost('nameChamp');
			$newLibelleChamp = $request->getPost('newLibelleChamp');
			$idListe = $request->getPost('idListe');
			$listeMode = $request->getPost('listeMode');

			## Chercher le state de la liste
			if ($listeMode == "id-modeDp") {
				$tableState = $this->getTableObjet('domiciliations_state')->select(array('idListe' => $idListe))->current();
			} else {
				$tableState = $this->getTableObjet('liste_state')->select(array('idListe' => $idListe))->current();
			}

			## Ajout du libelle
			$dataState = json_decode($tableState['data'], true);
			$dataState['filter'][$nameChamp]["libelle"] = trim($newLibelleChamp);

			if ($listeMode == "id-modeDp") {
				$update = $this->getTableObjet('domiciliations_state')->update(array('data' => json_encode($dataState)), array('idListe' => $idListe));
			} else {
				$update = $this->getTableObjet('liste_state')->update(array('data' => json_encode($dataState)), array('idListe' => $idListe));
			}

			return new JsonModel(array('success' => $update));
		}
	}

	//charger les lignes demandées en mode serverSide
	public function getServerJsonDataDpAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest() || $request->getPost()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$order		= $request->getPost('order');
			$jsonDpDatatableState = $request->getPost('jsonDpDatatableState');
			$idListe 	= (int) $request->getPost('idListe');

			$idDp 	= (int) $request->getPost('idDp', 0);
			$fetchMode 	= $request->getPost('fetchMode', '');
			$typeAppel = $request->getPost('typeAppel');//si on appel l'action depuis le controlleur ou la vue

			$liste = null;
			$typeListeObj = $typeListe = null;
			if ($idListe) {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();

				if ($liste) {
					$typeListeObj = $this->getTableObjet('type_domiciliations')->select(array('id' => $liste->idType))->current();
					$typeListe = $liste->idType;
				}
			}

			$columns = null;
			$from = $request->getPost('from', '');
			if ($jsonDpDatatableState && !empty($jsonDpDatatableState)) { // Appel champsmodal.phtml appliquer2 on change mode dp
				$columns = $jsonDpDatatableState['columns'];
			} else {
				$columns = $request->getPost('columns');
			}

			$startDate = $request->getPost('startDate', '');
			$endDate = $request->getPost('endDate', '');

			$startDate = date('Y-m-d', strtotime($startDate));
			$endDate = date('Y-m-d', strtotime($request->getPost('endDate') ? $request->getPost('endDate') : '01-01-2038'));

			## filtre bandeau
			$sessFB = new Container('filtreBandeau');
			$FiltresBandeau = isset($sessFB->filtres) ? $sessFB->filtres : array();

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : draw=$draw start=$start length=$length idListe=$idListe");
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : columns=".json_encode($columns));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : order=".json_encode($order));

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$codeTypeListe");

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('draw'	=> 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			// Lecture des descriptions des champs des logements
			if (empty($jsonDpDatatableState)) {
				$jsonDpDatatableState = $this->loadDomiciliationsState($idListe);
			}

			$jsonDpDatatableState	= $jsonDpDatatableState ? $jsonDpDatatableState['filter'] : [];
			//print_r($jsonDpDatatableState);exit();

			$jsonDpDatatableState['code'] = 'dp'; // A laisser juste avant le if

			$where	= array(); // Search filtres

			/*$listeChampsAffiches	= array(
					// nomLocataire et prenomLocataire sont préchargés dans loadModeDp => getlisteChampsAffiches()
					'idLocataire' => array('dyn'=>0, 'idTypeHtml'=>5, 'table'=>'domiciliations', 'equivalentSql'=>'idLocataire', 'visible'=>false),
					'idDp' => array('dyn'=>0, 'idTypeHtml'=>5, 'table'=>'domiciliations', 'equivalentSql'=>'id', 'visible'=>false),
					// 'etat' => array('dyn'=>0, 'idTypeHtml'=>3, 'table'=>'domiciliations', 'equivalentSql'=>'etat', 'visible'=>false, 'sourceListe' =>'domiciliations_etat'),
					// 'dateEntree' => array('dyn'=>0, 'idTypeHtml'=>2, 'table'=>'domiciliations', 'equivalentSql'=>'dateEntree', 'visible'=>false),
					// 'dateSortie' => array('dyn'=>0, 'idTypeHtml'=>2, 'table'=>'domiciliations', 'equivalentSql'=>'dateSortie', 'visible'=>false),
				);*/

			if ($jsonDpDatatableState && $columns) {

				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// var_dump($jsonDpDatatableState);die();
				// $formFields     = $this->getFormFields(0, $jsonDpDatatableState);
				$formFields     = $this->getDpFields($idListe, $jsonDpDatatableState);
				$formFields['dpFields']['code']->checked = false;
				// print_r($formFields['dpFields']);

				// $formFields['dpFields']['nomLocataire']['checked'] = true;
				// $formFields['dpFields']['prenomLocataire']['checked'] = true;
				// $formFields['dpFields']['dateEntree']['checked'] = true;
				// $formFields['dpFields']['dateSortie']['checked'] = true;
				// $formFields['dpFields']['etat']['checked'] = true;

				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				foreach ($columns as $_key => $_column) {
					$_colName	= $_column[data];
					// if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
					if ($_colName) {
						## Recherche du champ dans les différentes listes de champs
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($formFields as $_typeField => $_fields) {
							if ($_typeField == "activeFields") {
								continue;
							}

							if (($_field = $_fields[$_colName])) {
								if ($_field->equivalentSql == 'idDp' || $_field->equivalentSql == 'idLocataire') {
									$_field->equivalentSql = 'id';
								}
								if ($_typeField == 'dynFields') {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->idChamp,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);

									if (($_field->table == "champs_suivis" || $_field->table == "suivis") && $_field->idTypeSuivis) {
										$listeChampsAffiches[$_colName]['idTypeSuivis'] = $_field->idTypeSuivis;
									} elseif ($_field->table == "champs_catalogue" && $_field->idTypeCatalogue) {
										$listeChampsAffiches[$_colName]['idTypeCatalogue'] = $_field->idTypeCatalogue;
									}
								} else {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->id,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);

									if (($_field->table == "suivis") && $_field->idTypeSuivis) {
										$listeChampsAffiches[$_colName]['idTypeSuivis'] = $_field->idTypeSuivis;
									}
								}
								break;
							}
						}
						if (!$listeChampsAffiches[$_colName]) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : _colName=$_colName absent dans fields");
						}
					}
					/*if ($_column['search']['value'] != "") {
						if ($_column['name'] == "nomLocataire"){
							array_push($where, "locataires.nom LIKE '%".$_column['search']['value']."%'");
						}
						if($_column['name'] == "prenomLocataire"){
							array_push($where, "locataires.prenom LIKE '%".$_column['search']['value']."%'");
						}
						if ($_column['name'] == "dateEntree" || $_column['name'] == "dateSortie" ){
							$searchDateEntree = explode("|", $_column['search']['value']);
							$searchDateDebut = trim($searchDateEntree[0]) != "" ? $searchDateEntree[0] : "1970-01-01";
							$searchDateFin = trim($searchDateEntree[1]) != "" ? $searchDateEntree[1] : "2050-01-01";
							array_push($where, "domiciliations." . $_column['name'] . " BETWEEN '". $searchDateDebut . "' AND '" . $searchDateFin . "'");
						}
						if ($_column['name'] == "etat"){
							$valueEtatDp = $this->getTableObjet('domiciliations_etat')->select(array('nom'=>$_column['search']['value']))->current();
							array_push($where, "domiciliations.etat LIKE '%".$valueEtatDp['id']."%'");
						}
					}*/
				}

				$campagnesDeGest = [];
				## on vérifie si on a le droit d'attribution campagne, si oui on controle les campagnes sinon on affiche tout
				if($_SESSION['USERDROIT']['user-campagnes'] == 'W'){
					$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
					foreach ($gestionnaire_campagnes as $row) {
						$campagnesDeGest[] = $row->idCampagne;
					}
				}
				if (empty($campagnesDeGest)) {
					$campagnesDeGest[] = -1;
				}

				array_push($where, "IF(domiciliations.idCampagne > 0,domiciliations.idCampagne IN (".implode(',', $campagnesDeGest)."),1=1 )");


				if ($fetchMode == "oneRow" && $idDp > 0) {
					array_push($where, "domiciliations.id = $idDp");
				}
				$listeChampsAffichess    = $this->getlisteChampsAffiches($jsonDpDatatableFilter, $formFields, 'dp');
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffichess));
				$listeChampsAffiches = array_merge($listeChampsAffichess, $listeChampsAffiches);

				## Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// $listeChampsAffichesDB    = $this->getlisteChampsAffiches($jsonDpDatatableFilter, $formFields, 'dp');
				// syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffiches));
				// $listeChampsAffiches = array_merge($listeChampsAffichesDB, $listeChampsAffiches);
				// Colones de la liste
				// unset($formFieldsLoc['resaFields']);
				// unset($formFieldsLoc['demFields']);
				// unset($formFieldsLoc['dynFields']);

				// $formFieldsLoc['dynFields']['code']['checked'] = false;
				// $formFields['locFields']['dateNaissance']['checked'] = true;

				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$rowsAll = array();
				if ($from == "champsModalDp") {
					## sir on clique sur le bouton appliquer du modal champs , on charge cette partie que si on a des champs de type select
					$listeChampsAffichesSelect = array();
					$champExplicites = array();

					foreach ($listeChampsAffiches as $n => $attrs) {
						if ($attrs['idTypeHtml'] == 3) {
							$listeChampsAffichesSelect[$n] = $attrs;
						}
						if (in_array($n, array('idDp', 'idLocataire'))) {
							$champExplicites[$n] = $attrs;
						}
					}
					if (!empty($listeChampsAffichesSelect)) {
						$champsToRequete = array_merge($listeChampsAffichesSelect, $champExplicites);
						$rowsAll = $this->getAllDpFields($adapter, $typeListeObj, $champsToRequete, $where, array('config' => $conf, 'fetchMode' => $fetchMode, 'idDp' => $idDp, 'typeChargement' => 'header'));
					}
				} else {
					$rowsAll = $this->getAllDpFields($adapter, $typeListeObj, $listeChampsAffiches, $where, array('config' => $conf, 'fetchMode' => $fetchMode, 'idDp' => $idDp));
				}

				//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffiches));

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

				// $rowsAll = $this->getAllDpFields($adapter, $typeListe, $listeChampsAffiches, $where ,array('config'=>$conf));

				// echo "<pre>";
				// print_r($rowsAll);
				// echo "</pre>";
				// die();

				// $rowsAll = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where ,array('config'=>$conf));
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe count_rowsAll=".count($rowsAll)." debut_rowsAll=".json_encode(array_slice($rowsAll, 0, 1)));

				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);

				$selectOptions = array();

				if ($rowsAll) {

					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					$selectVals = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 /*|| $_col[idTypeHtml] == 19*/) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 3) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
								$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					## recup des bonne valeurs des champs de type radio selon la campagne
					$radioOptions = array();
					if (!empty($colRadios)) {
						$tableChampsForms = $this->getTableObjet('champs_formulaires');
						$select = $tableChampsForms->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where->in('equivalentSql', $colRadios);
						$champs = $tableChampsForms->selectWith($select);
						foreach ($champs as $ch) {
							$options = explode(";", $ch->options);
							$radioOptions[$ch->idCampagne][$ch->equivalentSql] = $options;
						}
					}


					if ($colDates || !empty($radioOptions) || !empty($selectVals)) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							if ($colDates) {
								foreach ($colDates as $_colName) {
									$rowValue	= $row[$_colName];
									if ($rowValue && strpos($rowValue, '-') == 2) {
										## Date au format dd-mm-yyyy -> il faut convertir
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $rowValue);
										$row[$_colName]		= "$yyyy-$mm-$dd";
									}
								}
							}
							foreach ($row as $_colName => $_value) {
								if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
									$_options	= $selectOptions[$_colName];
									if (trim($_value == "")) {
										$_value = 'null';
									}
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								}
							}
							## remplacer les valeurs radio avec les bonne valeurs
							if (!empty($radioOptions)) {
								foreach ($colRadios as $_colName) {
									if (in_array($_colName, $colRadios)) {
										if (!empty($radioOptions[$row['idCampagne']][$_colName][$row[$_colName]])) {
											$row[$_colName] = $radioOptions[$row['idCampagne']][$_colName][$row[$_colName]];
										} else {
											$row[$_colName] = "";
										}
									}
								}
							}

							##Select multiple
							if(!empty($selectVals)) {
								foreach($selectVals as $_colName => $sVals) {
									$rowValue	= $row[$_colName];
									if($rowValue) {
										$rowValueArr = explode(',', $rowValue);
										if(!empty($rowValueArr)) {
											$rowValueNew = '';
											foreach($rowValueArr as $v) {
												$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
												$rowValueNew .= ', ';
											}
											$rowValueNew = substr($rowValueNew, 0, -2);
											if($rowValueNew) {
												$row[$_colName]	= $rowValueNew;
											}
										}
									}
								}
							}
							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}


					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonDpDatatableState as $fieldName => $field) {
						if (isset($field['type']) && !empty($field['type'])) {
							$searchTypes[$fieldName]	= $field['type'];
							if (in_array($fieldName, $colRadios)) {
								$searchTypes[$fieldName]	= "text";
							}//traiter les champs radio comme des text
							if (in_array($fieldName, $colCheckbox)) {
								$searchTypes[$fieldName]	= "checkbox";
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));


					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column[name];
						$value		= $column[search][value];
						//si value == 'null' cad filtre sur valeur vide pour les select
						// si == " " filtre sur valeur vide champs texte
						if ($colName && $column[searchable] && ($value || $value == 'null' || $value == " ")) {
							$searchType	= $searchTypes[$colName];
							if ($value == 'null' || $value == " ") {
								$value = null;
							}
							if ($searchType == 'date' || $searchType == 'number' && $value) {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max, $vide)		= explode("|", $value);
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$searchs[$colName][min]		= $min;
								$searchs[$colName][max]		= $max;
								$searchs[$colName][vide]		= $vide;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$searchs[$colName][text]	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search['vide'] == '1') {
										$condVide = (trim($row[$search['colInd']]) != '' && substr($row[$search['colInd']], 0, 2) != "00");
										if ($search[min] != '') {
											if ($condVide && $rowValue < $search[min]) {
												continue 2;
											}
											if ($search[max] != '') {
												if ($condVide && $rowValue > $search[max]) {
													continue 2;
												}
											}
										} else {
											if ($search[max] != '') {
												if ($condVide && $rowValue > $search[max]) {
													continue 2;
												}
											} else {
												if ($condVide) {
													continue 2;
												}
											}
										}
									} else {
										//on ne prend pas en compte les dates vides:
										$condVide = (trim($row[$search['colInd']]) == '' || substr($row[$search['colInd']], 0, 2) == "00");
										if (($search[min] != '' || $search[max] != '') && $condVide) {
											continue 2;
										}
										if (($search[min] != '') && $rowValue < $search[min]) {
											continue 2;
										}
										if (($search[max] != '') && $rowValue > $search[max]) {
											continue 2;
										}
									}
								} elseif ($search['type'] == 'number') {
									if ($search[min] != '' && $rowValue < $search[min]) {
										continue 2;
									}
									if ($search[max] != '' && $rowValue > $search[max]) {
										continue 2;
									}
								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos(strtolower(utf8_decode($rowValue)), strtolower(utf8_decode($search['text']))) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}

					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSel=".count($rowsSel)." debut_rowsSel=".json_encode(array_slice($rowsSel, 0, 1)));
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}


				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
				// var_dump(count($rowsSlice));die();

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSlice=".count($rowsSlice)." rows_rowsSlice=".json_encode(array_slice($rowsSlice, 0, 1)));
			}

			$champsNonModifiables = array('idDp', 'idLocataire', 'nomLocataire', 'prenomLocataire');

			// $formFields['dynFields']['libre_Travailleur_sociale']->checked = true;

			// if ($formFields['dynFields']) $formFields['dynFields']['libre_Travailleur_sociale']['checked'] = true;
			// var_dump($columns);
			// die();

			/*if (count($rowsSlice) > 0) {
				$cpts	= array();
				for ($i=0; $i < count($rowsSlice); $i++) {
					$cpts[nbLignes]++;
					$rowsSliceArr = $rowsSlice[$i];
					if (is_object($rowsSliceArr)) {
						$rowsSliceArr = get_object_vars($rowsSliceArr);
					}

					$keysArr = array_keys($rowsSliceArr);
					foreach ($keysArr as $key => $value) {
						$champAffiche	= $listeChampsAffiches[$value];
						$cpts[nbColonnes]++;
						if (strpos($value, 'libre_') !== false) {
							$cpts[nbLibres]++;
							//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe nameChamps=$value idTypeHtml=$champAffiche[idTypeHtml] sourceListe=$champAffiche[sourceListe]");
							if ($champAffiche[idTypeHtml] == 18) {
								$cpts[nbMultiselect]++;
								// on récupère les valeurs correpondantes dans demandes_values
								$valeurs_select = $this->getTableObjet('valeurs_select')
								->select(array('idSelect' => $champAffiche[sourceListe]))->toArray();

								$valuesMultiple = "";
								$idsOrigin = explode(",", $rowsSlice[$i][$value]);

								foreach ($valeurs_select as $key => $vs) {
									foreach ($idsOrigin as $key => $idsO) {
										if ($vs['id'] == $idsO) {
											$valuesMultiple .= $vs['valeur'] . ", ";
										}
									}
								}

								$valuesMultiple = substr($valuesMultiple, 0, -2);
								if ($valuesMultiple) {
									$rowsSlice[$i][$value] = $valuesMultiple;
								}

								// echo "<pre>";
								// print_r($valuesMultiple);
								// echo "</pre>";
								// die();
							}
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe cpts=".json_encode($cpts));
			}*/

			//pour afficher le total de lignes d'une listes dans le tableau de bord
			if ($request->getPost() && $typeAppel == "controller") {
				return $output;
			}

			if ($request->getPost() && $typeAppel == "modeIndicateurs") {
				$output['data']	= $rowsSlice;
				return $output;
			}

			// lors de l'appel ajax provenant de view/liste/modedp.js.phtml seulement, on retourne directement les données sans envoyer la vue
			if ($from && $from == 'modedpjs') {
				## Sortie en tableau
				## ~~~~~~~~~~~~~~~~~
				//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe data=".count($rowsSlice));
				$output['data']	= $rowsSlice;
				$output['champs']	= $listeChampsAffiches;
				$view = new JsonModel($output);
				$view->setTerminal(true);
				return $view;
			}



			// sinon chargement initiale de la liste dp (view/liste/index.phtml)
			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/modedp')
				->setVariables(array(
					'rows' 		=> array(),
					'locFields' 	=> isset($formFields) ? $formFields['locFields'] : [],
					'dpFields' 	=> isset($formFields) ? $formFields['dpFields'] : [],
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'				=> 1,
					'jsonDpDatatableState' => $jsonDpDatatableState,
					'selectOptions'	=> $selectOptions,
					'idListe'	=> $idListe ? $idListe : null,
					'typeListe'	=> $typeListe ? $typeListe : null,
					'config' => $conf,
					// 'searchName' => $searchName,
					// 'searchPrenom' => $searchPrenom,
					'champsNonModifiables'	=> $champsNonModifiables,
					// 'modeles' => $modeles,
					// 'listes' => $allowedListe,
				));

			$htmlOutput = $this->getServiceLocator()
					->get('viewrenderer')
					->render($htmlViewPart);

			//syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe len_htmlOutput=".strlen($htmlOutput));
			$view = new JsonModel(array(
					'success' => true,
					'data' => $rowsSlice,
					'htmlOP' => $htmlOutput,
					'champs' => $listeChampsAffiches,
					'liste' => $liste,
					));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadmodeEdlAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$conf = $this->getConfigurationTable()->getConfig(1);
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$residenceResult = $this->getResidencesTable()->fetchByGest($gestId);
			$residences = array();
			$idsGR = array();
			foreach ($residenceResult as $resid) {
				$residences[$resid->id] = $resid;
				$idsGR[] = $resid->id;
			}

			// echo "<pre>";
			// var_dump($residences);
			// echo "</pre>";
			// die();

			$edlBaseParametres = $this->getEdlParametresTable()->fetchAll()->toArray();
			$user_proprio = $edlBaseParametres[0]['user_proprio'];

			if ($user_proprio != "") {
				$user_proprio = explode(',', $user_proprio);
			}

			// controle des edls proprio par utilisateur
			$user_role_linker	= $this->getTableObjet('user_role_linker')
			->select(array('user_id' => $gestId))->current();

			$peutVoirEdlProprio = false;
			if (count($user_proprio) > 0 && in_array($user_role_linker->role_id, $user_proprio)) {
				$peutVoirEdlProprio = true;
			}

			$batiments = array();
			if ($request->getPost('filter')) {
				$dateDebut = date("Y-m-d", strtotime($request->getPost('dateDebut')));
				$dateFin = date("Y-m-d", strtotime($request->getPost('dateFin')));
				$nomLocataire = $request->getPost('nomLocataire', '');
				$prenomLocataire = $request->getPost('prenomLocataire', '');
				$numeroChambre = $request->getPost('numeroChambre', '');
				$idsResidence = $request->getPost('idsResidence', null);
				$idsBatiment = $request->getPost('idsBatiment', null);

				$tables = $where = $filters = array();
				if ($nomLocataire) {
					$where[] = "locataires.nom LIKE '%$nomLocataire%'";
					$tables[] = 'locataires';
				}
				if ($prenomLocataire) {
					$where[] = "locataires.prenom LIKE '%$prenomLocataire%'";
					$tables[] = 'locataires';
				}
				if ($numeroChambre) {
					$where[] = "logements.numero LIKE '%$numeroChambre%'";
					$tables[] = 'logements';
				}
				if (!empty($idsBatiment)) {
					$where[] = "batiments.id IN (".implode(',', $idsBatiment).")";
					$tables[] = 'batiments';
				}
				if (!empty($idsResidence)) {
					$where[] = "batiments.idResidence IN (".implode(',', $idsResidence).")";
					$tables[] = 'batiments';
				} else {
					// pas de filtre par résidences alors on prend celui que l'utilisateur a droit par défaut
					$where[] = "batiments.idResidence IN (".implode(',', $idsGR).")";
					$tables[] = 'batiments';
				}

				$filters['tables'] = $tables;

				//chargement des batiments par residences
				if (!empty($idsResidence)) {
					$batimentResult = $this->getBatimentTable()->getBatimentsDeResidence($idsResidence);
					foreach ($batimentResult as $r) {
						$batiments[$r->id] = $r;
					}
				}

				if ($dateFin == '1970-01-01') {
					$dateFin = date('Y-m-d');
				}

				// $residencesArr = $this->getTableObjet('gestionnaire_residences')
				// ->select(array('idGestionnaire' => $gestId))->toArray();
				// $idsGResidences = [];

				$edlsTable = $this->getEdlTable()->fetchAllByCreationDate($dateDebut, $dateFin, $where, $filters)->toArray();

				// echo "<pre>";
				// print_r($edlsTable);
				// echo "</pre>";
				// die();

				// echo "<pre>";
				// var_dump($idsBatiment);
				// echo "</pre>";
				// die();

				$edls = array();
				foreach ($edlsTable as $keyEdl => $edl) {
					// récupération des infos de la resa
					if (intval($edl['id_reservations']) > 0) {
						$resaRow = $this->getTableObjet('reservations')
						->select(array('id' => $edl['id_reservations']))->current();
						if ($resaRow) {
							$edl['remise_des_cles'] = $resaRow->remise_des_cles;
							$edl['idReservation'] = $resaRow->id;
							$edl['numeroChambre'] = $resaRow->numeroChambre;
						}
					}

					// récupération des infos locataires
					if (intval($edl['id_locataire']) > 0) {
						$locRow = $this->getTableObjet('locataires')
						->select(array('id' => $edl['id_locataire']))->current();
						if ($locRow) {
							$edl['idLoc'] = $locRow->id;
							$edl['nom'] = $locRow->nom;
							$edl['prenom'] = $locRow->prenom;
						}
					}

					// si l'edl courant c'est un edl proprio mais que l'utilisateur connecté n'a pas les droits alors on continue
					if ($edl['proprietaire'] == '1' && count($user_proprio) > 0 && !in_array($user_role_linker->role_id, $user_proprio)) {
						continue;
					}

					$resid = $this->getLogementTable()->getResidenceDeLogement($edl['id_logement']);
					if ($resid) {
						$edl['batiment'] = $resid->batiment;
						$edl['residence'] = $resid->residence;
						$edl['numero'] = $resid->numero;
					}

					$etatEdl = $edl['etat'];
					if ($edl['etat'] == 'terminer') {
						$etatEdl = 'terminé';
					} elseif ($edl['etat'] == 'encours') {
						$etatEdl = 'en cours';
					}

					$dateRevalidationEdl = '';
					if (!empty($edl['date_revalidation'])) {
						$dateRevalidationEdl = date("d-m-Y", strtotime($edl['date_revalidation']));
					}

					$renonceEdl = $edl['renonce'];
					if (!empty($edl['renonce']) && $edl['renonce'] == '1') {
						$renonceEdl = 'oui';
					} elseif (!empty($edl['renonce']) && $edl['renonce'] == '0') {
						$renonceEdl = 'non';
					}

					$controlEdl = $edl['edl_control'];
					// if($edl['type'] == 'entrant'){
					if (trim($controlEdl) == 'acontroler') {
						$controlEdl = 'à contrôler';
					} elseif (trim($controlEdl) == 'controler') {
						$controlEdl = 'contrôlé';
					} elseif (trim($controlEdl) == 'encoursdecontrole') {
						$controlEdl = 'en cours de contrôle';
					}
					// }

					$dateEdl = '';
					if (!empty($edl['date_revalidation']) && strtotime($edl['date_revalidation']) > strtotime($edl['date'])) {
						$dateEdl = date("d-m-Y", strtotime($edl['date_revalidation']));
					} else {
						$dateEdl = date("d-m-Y", strtotime($edl['date']));
					}

					$prestationsEdl = '';
					if (!empty($edl['edl_etat_prestations'])) {
						$prestationsEdl = $edl['edl_etat_prestations'];
					}

					$clesEdl = '';
					if ($edl['etat'] == 'terminé' && $edl['type'] == 'sortant') {
						$clesEdl = $edl['remise_des_cles'];
					}

					// former le tableau avec la bonne Structure
					$locataire = $this->getLocatairesTable()->getLocataire($edl['id_locataire']);
					$userTable = $this->getTableObjet('user')->select(array('user_id' => (int) $edl['user_id']))->current();

					// On vérifie si l'edl possède des interventions techniques
					$travaux = $this->getTableObjet('demandes')
					->select(array('idEdl' => (int) $edl['id'], 'fromTabletteEdl' => 1))->toArray();

					$tableRow = array(
						'idEdl' => $edl['id'],
						'idReservation' => $edl['id_reservations'],
						'idLocataire' => $edl['id_locataire'],
						'nom' => $locataire->nom,
						'prenom' => $locataire->prenom,
						'numeroLogement' => $edl['numero'],
						'residence' => $edl['residence'],
						'batiment' => $edl['batiment'],
						'typeEdl' => $edl['type'],
						'typeValidationEdl' => $edl['type_validation'],
						'etatEdl' => $etatEdl,
						'dateRevalidationEdl' => $dateRevalidationEdl,
						'renonceEdl' => $renonceEdl,
						'controlEdl' => $controlEdl,
						'dateEdl' => $dateEdl,
						'observationsGlobales' => $edl['observations_globales'],
						'prestations' => $prestationsEdl,
						'proprietaire' => $edl['proprietaire'] == '1' ? 'Oui' : '',
						'cles' => $clesEdl,
						'utilisateur' => $userTable ? $userTable->display_name : '',
						'travaux' => count($travaux) > 0 ? 'Oui' : '',
					);
					array_push($edls, $tableRow);
				}

				$menuForm = $this->getTableObjet('droit_elements')
				->select(array('unique_name' => 'mode-input-form'))->current();

				$demandesType = $this->getTableObjet('demandes_type')
				->select(array('tabNom' => 'travaux'))->current();

				return new JsonModel(array('data' => $edls,
											'peutVoirEdlProprio' => $peutVoirEdlProprio,
											'menuForm' => $menuForm,
											'demandesType' => $demandesType,
											'nomLocataire' => $nomLocataire,
											'prenomLocataire' => $prenomLocataire,
											'numeroChambre' => $numeroChambre,
											'residences' => $residences,
											'batiments' => $batiments,
											'idsResidence' => $idsResidence,
											'idsBatiment' => $idsBatiment,
											'config' => $conf,
											));
			}

			$edls = $this->getEdlTable()->fetchAll()->toArray();
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modeedl')
			->setVariables(array('residences' => $residences, 'batiments' => $batiments, 'config' => $conf,
				'peutVoirEdlProprio' => $peutVoirEdlProprio,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array('success' => true, 'htmlOP' => $htmlOutput));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadBoutiqueFormState($idListe)
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] AAK: type=$type");
		$formStateArr	= array();
		$formStateObj	= $this->getTableObjet('champs_boutique_save')->select(array('idListe' => $idListe))->current();
		if ($formStateObj) {
			$formState	= json_decode($formStateObj->fields, 1);
			if (array_key_exists('filter', $formState)) {
				$formStateArr	= $formState;
			} elseif (!empty($formState)) {
				## Peut-être l'ancien format
				## ~~~~~~~~~~~~~~~~~~~~~~~~~
				$formStateArr['filter']	= $formState;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] AAK: type=$type oldFormat");
			}
		}
		return	$formStateArr;
	}

	public function fetchListAllBoutique($tableName = "boutique_liste")
	{
		$tableObj = new Tables($tableName, $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select = $tableObj->getTable()->getSql()->select();
		$select->join('boutique_type_liste', 'boutique_liste.idType = boutique_type_liste.id', ['type'], 'left');
		$select->where(array('deleted' => '0'));
		$select->order(array('nom ASC'));
		$resultSet = $tableObj->getTable()->selectWith($select)->current();
		return $resultSet;
	}

	public function fetchAllByProfileBoutique($tableName = "boutique_liste", $idProfile, $adapter = null)
	{
		$tableObj = new Tables($tableName, $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select = $tableObj->getTable()->getSql()->select();

		$select->join('boutique_type_liste', 'boutique_liste.idType = boutique_type_liste.id', ['type'], 'left');
		$select->join('boutique_liste_profile', 'boutique_liste.id = boutique_liste_profile.idListe', [], 'left');
		$select->where(array('deleted' => '0', 'boutique_liste_profile.idProfile' => $idProfile));
		$select->order(array('nom ASC'));
		$resultSet = $tableObj->getTable()->selectWith($select);
		return $resultSet;
	}

	public function fetchAllPrivateBoutique($tableName = "boutique_liste", $idUser, $adapter = null)
	{
		$tableObj = new Tables($tableName, $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		$select = $tableObj->getTable()->getSql()->select();

		$select->join('boutique_type_liste', 'boutique_liste.idType = boutique_type_liste.id', ['type'], 'left');
		$select->where(array('deleted' => '0', 'boutique_liste.idEtat' => 1, 'boutique_liste.idUser' => $idUser));
		$select->order(array('nom ASC'));
		$resultSet = $tableObj->getTable()->selectWith($select);
		return $resultSet;
	}

	public function loadmodeBoutiqueAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$conf = $this->getConfigurationTable()->getConfig(1);
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$allListes = $this->fetchListAllBoutique("boutique_liste");
			$allowedListe = array();
			$idDemande = "";

			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			$allListes = $this->fetchAllByProfileBoutique("boutique_liste", $idProfile, $adapter);

			foreach ($allListes as $liste) {
				//on affiche les listes public
				$nom = $liste->nom;
				if ($liste->type) {
					$nom .= ' ('.$liste->type.')';
				}

				if ($liste->idType == '1') {
					$idDemande = $liste->id;
				}

				if ($liste->idEtat == '2') {
					$allowedListe[$liste->id] = $nom;
				} elseif ($liste->idUser == $gestId) {
					$allowedListe[$liste->id] = $nom;
				}
			}

			$privateListes = $this->fetchAllPrivateBoutique("boutique_liste", $gestId);
			if ($privateListes) {
				foreach ($privateListes as $liste) {
					$l = (object)$liste;
					$allowedListe[$l->id] = $l->nom;
				}
			}

			// asort($allowedListe);

			$allProfiles	= $this->getTableObjet('user_role')->select();
			$allowedProfiles = array();
			if ($allProfiles) {
				foreach ($allProfiles as $row) {
					if ($row->role_id != 'guest' && $row->role_id != 'user') {
						$allowedProfiles[]	= $row;
					}
				}
			}

			// var_dump($allowedListe);die();

			$typesListeRes = $this->getTableObjet('boutique_type_liste')->select();
			$typesListe = array();
			foreach ($typesListeRes as $row) {
				$typesListe[$row->id] = $row;
			}

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modeboutique')
			->setVariables(array(
				'types' => $allowedListe,
				'typesListe' => $typesListe,
				'profiles' => $allowedProfiles,
				'config' => $config,
				'champModalHtml' => $this->loadChampsModal(),
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);


			$view = new JsonModel(array('success' => true, 'htmlOP' => $htmlOutput));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function getTypeBoutiqueListeCode($idListe)
	{
		$table = $this->getTableObjet('boutique_liste');
		$select = $table->getSql()->select();
		$select->join('boutique_type_liste', 'boutique_type_liste.id = boutique_liste.idTypeListe', array('idTL' => 'id', 'codeType'));
		$select->where(array('boutique_liste.id' => $idListe));
		$row = $table->selectWith($select)->current();
		return $row ? $row->codeType : '';
	}

	public function fetchEdlRowAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idLocataire = $request->getPost('idLocataire');
			$idEdl = $request->getPost('idEdl');

			$edl = $this->getTableObjet('edl')->select(array('id' => $idEdl))->current();
			$locataire = $this->getTableObjet('locataires')->select(array('id' => $idLocataire))->current();

			$resid = $this->getLogementTable()->getResidenceDeLogement($edl['id_logement']);
			if ($resid) {
				$edl['batiment'] = $resid->batiment;
				$edl['residence'] = $resid->residence;
				$edl['numero'] = $resid->numero;
			}

			$etatEdl = $edl['etat'];
			if ($edl['etat'] == 'terminer') {
				$etatEdl = 'terminé';
			} elseif ($edl['etat'] == 'encours') {
				$etatEdl = 'en cours';
			}

			$dateRevalidationEdl = '';
			if (!empty($edl['date_revalidation'])) {
				$dateRevalidationEdl = date("d-m-Y", strtotime($edl['date_revalidation']));
			}

			$renonceEdl = $edl['renonce'];
			if (!empty($edl['renonce']) && $edl['renonce'] == '1') {
				$renonceEdl = 'oui';
			} elseif (!empty($edl['renonce']) && $edl['renonce'] == '0') {
				$renonceEdl = 'non';
			}

			$controlEdl = $edl['edl_control'];
			if (trim($controlEdl) == 'acontroler') {
				$controlEdl = 'à contrôler';
			} elseif (trim($controlEdl) == 'controler') {
				$controlEdl = 'contrôlé';
			} elseif (trim($controlEdl) == 'encoursdecontrole') {
				$controlEdl = 'en cours de contrôle';
			}

			$dateEdl = '';
			if (!empty($edl['date_revalidation']) && strtotime($edl['date_revalidation']) > strtotime($edl['date'])) {
				$dateEdl = date("d-m-Y", strtotime($edl['date_revalidation']));
			} else {
				$dateEdl = date("d-m-Y", strtotime($edl['date']));
			}

			$prestationsEdl = '';
			if (!empty($edl['edl_etat_prestations'])) {
				$prestationsEdl = $edl['edl_etat_prestations'];
			}

			$clesEdl = '';
			if ($edl['etat'] == 'terminé' && $edl['type'] == 'sortant') {
				$clesEdl = $edl['remise_des_cles'];
			}

			// former le tableau avec la bonne Structure
			$locataire = $this->getLocatairesTable()->getLocataire($edl['id_locataire']);
			$userTable = $this->getTableObjet('user')->select(array('user_id' => (int) $edl['user_id']))->current();

			// On vérifie si l'edl possède des interventions techniques
			$travaux = $this->getTableObjet('demandes')
			->select(array('idEdl' => (int) $edl['id'], 'fromTabletteEdl' => 1))->toArray();

			$data = array(
				'idEdl' => $edl['id'],
				'idReservation' => $edl['id_reservations'],
				'idLocataire' => $edl['id_locataire'],
				'nom' => $locataire->nom,
				'prenom' => $locataire->prenom,
				'numeroLogement' => $edl['numero'],
				'residence' => $edl['residence'],
				'batiment' => $edl['batiment'],
				'typeEdl' => $edl['type'],
				'typeValidationEdl' => $edl['type_validation'],
				'etatEdl' => $etatEdl,
				'dateRevalidationEdl' => $dateRevalidationEdl,
				'renonceEdl' => $renonceEdl,
				'controlEdl' => $controlEdl,
				'dateEdl' => $dateEdl,
				'observationsGlobales' => $edl['observations_globales'],
				'prestations' => $prestationsEdl,
				'cles' => $clesEdl,
				'utilisateur' => $userTable ? $userTable->display_name : '',
				'travaux' => count($travaux) > 0 ? 'Oui' : '',
			);

			$view = new JsonModel(array('success' => true, 'data' => $data));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function loadmodeFinancierAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			if ($request->isGet()) {
				$prestations = $this->getTableObjet('prestations')->select(array('modePrestation' => 'fixe'))->toArray();
				for ($i = 0; $i < count($prestations); $i++) {
					$prestations[$i]['idPrestation'] = $prestations[$i]['id'];

					// fetch types
					$prestations[$i]['types'] = array();

					$prestations_to_types = $this->getTableObjet('prestations_to_types')->select(
						array(
							'id_prestations' => (int) $prestations[$i]['id'],
						)
					)->toArray();
					$prestations[$i]['types'] = $prestations_to_types;
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] nbPrestations=".count($prestations));

				// Fetch all presta from bredea
				$prestationsFromAllPms = array();
				$conf = $this->getConfigurationTable()->getConfig(1);
				if ($conf && $conf->bredea == 1) {
					try {
						## Pour tous les PMS, lecture de la liste des types de prestations dans le PMS
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$apipmss	= $this->getApipmsTable()->getAllActiveApi();
						if ($apipmss) {
							foreach ($apipmss as $apipms) {
								$idApiPms	= $apipms->id;

								if ($idApiPms) {
									$bredea		= null;
									$this->initPMS($idApiPms);

									## Traitement en fonction du PMS
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									if ($this->pms) {
										$prestationsFromPms = array();
										if ($this->pms->getClassName() === "Bredea") {
											$bredea	= $this->pms;
											if ($bredea) {
												$rows = $bredea->getRows('001fprest'/*, array('pre_typeprest' => 'IN')*/);

												for ($i = 0; $i < count($rows); $i++) {
													$rows[$i]['code'] = $rows[$i]['pre_code'];
													$rows[$i]['pre_lib'] = utf8_encode($rows[$i]['pre_lib']);
													$rows[$i]['description'] = utf8_encode($rows[$i]['pre_lib']);
													$rows[$i]['pre_comment'] = utf8_encode($rows[$i]['pre_comment']);
													array_push($prestationsFromPms, $rows[$i]);
												}
												$bredea->closeConnect();
												$this->pms	= null;
											}
										} elseif ($this->pms->getClassName() === "CeriFoyer") {
											$prestationsFromPms	= $this->pms->getListPrestations();
										}
										$this->pms		= null;
										if ($prestationsFromPms) {
											$prestationsFromAllPms	= array_merge($prestationsFromAllPms, $prestationsFromPms);
										}
									}
								}
							}
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :ListeController.php loadmodeFinancierAction Exception=".$ex->getMessage());
						//echo $ex->getMessage();
					}
				}
				$prestations_types = $this->getTableObjet('prestations_types')->select(array())->toArray();
				$data = array('data' => $prestations, "prestationsTypes" => $prestations_types, "prestations" => $prestations, "prestationsFromBredea" => $prestationsFromAllPms);
				return new JsonModel($data);
			}
		}
	}

	private function triPrestations($a, $b)
	{
		##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] a=$a[description] b=$b[description]");
		return strcasecmp($a[description], $b[description]);
	}

	public function loadmodeSerruresAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$userTable = $this->getTableObjet('user');
		$clesTable = $this->getTableObjet('cles');
		$clesToResasTable = $this->getTableObjet('clesToResas');
		$clesToLogementTable = $this->getTableObjet('clesToLogements');
		$clesToZonesTable = $this->getTableObjet('clesToZones');
		$locatairesTable = $this->getTableObjet('locataires');
		$resasTable = $this->getTableObjet('reservations');

		if ($request->isXmlHttpRequest()) {
			$sql = "SELECT * FROM zones";
			$zones = $adapter->query($sql, array())->toArray();

			if ($request->getPost('filter')) {
				// Recuperation de toutes les reservations confirmé(3), parti(6) et accueilli(7)
				$sql = "SELECT * FROM reservations WHERE (etat = 6 OR etat = 3 OR etat = 7) AND archive = '0' GROUP BY idLocataire DESC";
				$rows = $adapter->query($sql, array())->toArray();


				$resas = array();

				foreach ($rows as $keyRow => $row) {
					$sql = '';
					$idResa = $row['id'];

					$locataire = $this->getLocatairesTable()->getLocataire($row['idLocataire']);

					$rowData = array();
					$rowData['id'] = $idResa;
					$rowData['idLocataire'] = $locataire->id;
					$rowData['dateArrivee'] = $row['dateArrivee'];
					$rowData['dateDepart'] = $row['dateDepart'];

					$resid = $this->getLogementTable()->getResidenceDeLogement($row['idLogement']);
					if ($resid) {
						$rowData['batiment'] = $resid->batiment;
						$rowData['residence'] = $resid->residence;
						$rowData['numero'] = $resid->numero;
					}

					$locataireRow = array('nom' => $locataire->nom, 'prenom' => $locataire->prenom, 'telephoneMobile' => $locataire->telephoneMobile);

					$sql = "SELECT * FROM clesToResas WHERE idResa = $idResa";
					$clesToResas = $adapter->query($sql, array())->toArray();

					$clesPrincipale = $clesSupp1 = $clesSupp2 = "null";
					$clesPrincipaleType = $clesSupp1Type = $clesSupp2Type = '';
					$idClesPrincipale = $idClesSupp1 = $idClesSupp2 = null;
					$cles = array();
					if (count($clesToResas) > 0) {
						// Pour chaque résultat on récupere les infos de la clé
						$clesRows = array('clesToResas' => null, 'cles' => null);
						$clesRows['clesToResas'] = $clesToResas;

						$nbCles = count($clesRows['clesToResas']);
						// Pour chaque clés on récupere toutes les informations possibles
						for ($i = 0; $i < $nbCles; $i++) {
							$idCles = $clesRows['clesToResas'][$i]['idCles'];
							$sql = "SELECT * FROM cles WHERE id = $idCles";
							$cle = $adapter->query($sql, array())->toArray();

							// On récupere les zones autoriser pour la clé
							$sql = "SELECT *
									FROM clesToZones, zones
									WHERE clesToZones.idZones = zones.id
									AND clesToZones.idCles = $idCles";
							$cle[0]['zones'] = $adapter->query($sql, array())->toArray();

							// récuperation des logements
							$cle[0]['logements'] = $clesToLogementTable->select(array('idCles' => (int) $idCles))->toArray();
							$cles[] = $cle[0];
						}

						for ($i = 0; $i < count($cles); $i++) {
							if ($cles[$i]['type'] == 'p') {
								$clesPrincipale =  $cles[$i]['active'] === '1' ? 'activée' : 'désactivée';
								$clesPrincipaleType = $cles[$i]['peripherique'];
								$idClesPrincipale = $cles[$i]['id'];
							} elseif ($cles[$i]['type'] == '1') {
								$clesSupp1 =  $cles[$i]['active'] === '1' ? 'activée' : 'désactivée';
								$clesSupp1Type = $cles[$i]['peripherique'];
								$idClesSupp1 = $cles[$i]['id'];
							} elseif ($cles[$i]['type'] == '2') {
								$clesSupp2 =  $cles[$i]['active'] === '1' ? 'activée' : 'désactivée';
								$clesSupp2Type = $cles[$i]['peripherique'];
								$idClesSupp2 = $cles[$i]['id'];
							}
						}
					}

					// récuperation des infos locataires

					// $rowData['idLocataire'] = $locataire->id;
					// $rowData['idLocataire'] = $locataire->id;

					// récuperation des infos de la resa


					$idCles = array("idClesPrincipale" => $idClesPrincipale, 'idClesSupp1' => $idClesSupp1, 'idClesSupp2' => $idClesSupp1);
					$clesActives = array("clesPrincipale" => $clesPrincipale, "clesSupp1" => $clesSupp1, "clesSupp2" => $clesSupp2);
					$clesTypeActives = array("clesPrincipaleType" => $clesPrincipaleType, "clesSupp1Type" => $clesSupp1Type, "clesSupp2Type" => $clesSupp2Type);

					$rowMerge = array_merge($rowData, $locataireRow, $clesActives, $clesTypeActives, $idCles);
					$rowMerge['cles'] = count($cles) > 0 ? $cles : array();
					array_push($resas, $rowMerge);
				}

				return new JsonModel(array('data' => $resas, 'zones' => $zones));
			} elseif ($request->getPost('from') && ($request->getPost('from') == 'edit' || $request->getPost('from') == 'checkIn')) {
				// Récuperation des infos de l'utiliiateur via l'id
				return new JsonModel(array('zones' => $zones, 'id' => $request->getPost('id') ? $id : ''));
			}

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modeserrures')
			->setVariables(array());

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array('success' => true, 'htmlOP' => $htmlOutput));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function getKeysAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$clesTable = $this->getTableObjet('cles');
		$clesToResasTable = $this->getTableObjet('clesToResas');
		$clesToLogementTable = $this->getTableObjet('clesToLogements');
		$logementsTable = $this->getTableObjet('logements');
		$clesToZonesTable = $this->getTableObjet('clesToZones');
		$locatairesTable = $this->getTableObjet('locataires');
		$resasTable = $this->getTableObjet('reservations');

		if ($request->isXmlHttpRequest()) {
			if ($request->getPost('idResa')) {
				$idResa = $request->getPost('idResa');
				$sql = "SELECT * FROM clesToResas WHERE idResa = $idResa";
				$clesToResas = $adapter->query($sql, array())->toArray();
				$cles = array();

				if (count($clesToResas) > 0) {
					// Pour chaque résultat on récupere les infos de la clé

					$nbCles = count($clesToResas);
					// Pour chaque clés on récupere toutes les informations possibles
					for ($i = 0; $i < $nbCles; $i++) {
						$idCles = $clesToResas[$i]['idCles'];
						$sql = "SELECT * FROM cles WHERE id = $idCles";
						$cle = $adapter->query($sql, array())->toArray();

						// On récupere les zones autoriser pour la clé
						$sql = "SELECT *
								FROM clesToZones, zones
								WHERE clesToZones.idZones = zones.id
								AND clesToZones.idCles = $idCles";
						$cle[0]['zones'] = $adapter->query($sql, array())->toArray();

						// Récuperation des logements
						$clesToLogement = $clesToLogementTable->select(array('idCles' => (int) $idCles))->toArray();
						foreach ($clesToLogement as $key => $clesToLogementValue) {
							$cle[0]['logements'][] = $logementsTable->select(array('id' => (int) $clesToLogementValue['idLogement']))->current();
						}

						$cles[] = $cle[0];
					}
				}
			} elseif ($request->getPost('user_id')) {
				// On récupère que la clé principale
				$user_id = $request->getPost('user_id');
				$sql = "SELECT * FROM clesToResas WHERE idUser = $user_id";
				$clesToResas = $adapter->query($sql, array())->toArray();
				$cles = array();

				if (count($clesToResas) > 0) {
					$nbCles = count($clesToResas);
					// Pour chaque clés on récupere toutes les informations possibles
					$idCles = $clesToResas[0]['idCles'];
					$sql = "SELECT * FROM cles WHERE id = $idCles";
					$cle = $adapter->query($sql, array())->toArray();

					// On récupere les zones autoriser pour la clé
					$sql = "SELECT *
							FROM clesToZones, zones
							WHERE clesToZones.idZones = zones.id
							AND clesToZones.idCles = $idCles";
					$cle[0]['zones'] = $adapter->query($sql, array())->toArray();

					// Récuperation des logements
					$clesToLogement = $clesToLogementTable->select(array('idCles' => (int) $idCles))->toArray();
					foreach ($clesToLogement as $key => $clesToLogementValue) {
						$cle[0]['logements'][] = $logementsTable->select(array('id' => (int) $clesToLogementValue['idLogement']))->current();
					}

					$cles[] = $cle[0];
				}
			}
			return new JsonModel(array('cles' => $cles));
		}
	}

	public function updateSerruresAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$sql = new Sql($adapter);

		$clesTable = $this->getTableObjet('cles');
		$clesToResasTable = $this->getTableObjet('clesToResas');
		$clesToLogementTable = $this->getTableObjet('clesToLogements');
		$clesToZonesTable = $this->getTableObjet('clesToZones');
		$locatairesTable = $this->getTableObjet('locataires');
		$resasTable = $this->getTableObjet('reservations');

		if ($request->isXmlHttpRequest()) {
			$data = $request->getPost('infos');

			$idResa = $data['idResa'];
			$idLocataire = $data['idLocataire'];

			$date_array = explode(" ", $data['dateDebutValidite']);
			$hhmmDebut = str_replace(':', '', $date_array[1]);
			$date_format = explode("-", $date_array[0]);
			$var_day_debut = $date_format[2];
			$var_month_debut = $date_format[1];
			$var_year_debut = $date_format[0];

			$date_array = explode(" ", $data['dateFinValidite']);
			$hhmmFin = str_replace(':', '', $date_array[1]);
			$date_format = explode("-", $date_array[0]);
			$var_day_fin = $date_format[2];
			$var_month_fin = $date_format[1];
			$var_year_fin = $date_format[0];

			$data['startDateTime'] = $hhmmDebut.$var_day_debut.$var_month_debut.substr($var_year_debut, 2);
			$data['expiringDateTime'] = $hhmmFin.$var_day_fin.$var_month_fin.substr($var_year_fin, 2);

			$login = '';
			if ($data['type'] !== 'p' && $data['idCle'] !== '') {
				$login = join('-', explode(' ', strtolower(trim($data['nom'])))).'-'.$data['idCle'];
			}

			// On génère le token utilisateur
			$token = bin2hex(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'));

			$clesData = array(
				'nom' => $data['nom'],
				'prenom' => $data['prenom'],
				'telephone' => $data['telephone'],
				'dateDebutValidite' => $data['dateDebutValidite'],
				'dateFinValidite' => $data['dateFinValidite'],
				'type' => $data['type'],
				'peripherique' => $data['peripherique'],
				'active' => $data['active'],
				'login' => $login,
				'password' => $data['type'] !== 'p' ? $data['password'] : '',
				'token' => $data['type'] !== 'p' ? $token : '',
			);

			$resp = array();

			// on met à jour le numéro de téléphone de la table locataire
			$locatairesTable->update(array('telephoneMobile' => $data['telephone']), array('id' => (int) $idLocataire));

			// Recup infos locataire
			$locataire = $locatairesTable->select(array('id' => (int) $idLocataire))->current();
			$resa = $resasTable->select(array('id' => (int) $idResa))->current();

			// on vérifie si c'est une insertion ou c'est une mises à jour (si idCle n'est pas null)
			if ($data['idCle'] == '') {
				$clesTable->insert($clesData);
				$idClesInserted = $adapter->getDriver()->getLastGeneratedValue();

				// On màj le nom d'utilisateur que si c'est pas
				if ($data['type'] !== 'p') {
					$login = join('-', explode(' ', strtolower(trim($data['nom'])))).'-'.$idClesInserted;
				}
				$clesTable->update(array('login' => $login), array('id' => (int) $idClesInserted));

				// Après avoir insérer la clé on insère clesToResas
				$clesToResasTable->insert(array('idCles' => $idClesInserted, 'idResa' => $data['idResa'], 'idUser' => $data['idUser']));

				// Et à la fin on insère les zones
				if (count($data['zones']) > 0) {
					foreach ($data['zones'] as $key => $zone) {
						$clesToZonesTable->insert(array('idCles' => $idClesInserted, 'idZones' => $zone['id']));
					}
				}
			} else {
				// c'est une màj de la clé (+ reset les zones)
				// if ($data['ajaxFrom'] === 'modeSerrure.js.phtml') {
				// $clesData = array(
				//     'nom'=> $locataire->nom,
				//     'prenom'=> $locataire->prenom,
				//     'telephone'=> $locataire->telephoneMobile,
				//     'dateDebutValidite'=> $resa->dateArrivee,
				//     'dateFinValidite'=> $resa->dateDepart,
				//     'type'=> $data['type'],
				//     'peripherique'=> $data['peripherique'],
				//   		'active' => $data['active'],
				//   		'login' => join('-', explode(' ', strtolower($data['nom']))).'-'.$data['idCle'],
				//   		'password' => $data['password'],
				//   		'token' => $data['type'] != 'p' ? $token : '',
				// );
				// }

				$clesTable->update($clesData, array('id' => (int) $data['idCle']));

				// On supprime les zones de la clés puis on recrée de nouveau
				$clesToZonesTable->delete(array('idCles' => (int) $data['idCle']));

				if (count($data['zones']) > 0) {
					foreach ($data['zones'] as $key => $zone) {
						$clesToZonesTable->insert(array('idCles' => $data['idCle'], 'idZones' => $zone['id']));
					}
				}
			}

			// var_dump($data);die();

			// On met à jour la liste des logements
			// 1. On supprime tous les logements appartenant à la clé
			// 2. On execute les insertions
			$logementsInserted = 0;
			$idCles = empty($data['idCle']) ? $idClesInserted : $data['idCle'];
			$clesToLogementTable->delete(array('idCles' => (int) $idCles));
			if (count($data['logements']) > 0) {
				for ($i = 0; $i < count($data['logements']); $i++) {
					$clesToLogementRow = array('idCles' => (int) $idCles, 'idLogement' => (int) $data['logements'][$i]);
					$inserted = $clesToLogementTable->insert($clesToLogementRow);
					$logementsInserted += $inserted ? 1 : 0;
				}
			}

			// Si encodeur coché alors encodé une carte
			if ($data['active'] === '1' && $data['peripherique'] == 'encodeur') {
				$resp = $this->encodeSerrures($data);
			} else {
				// Executer la commande de clé perdue
				$resp = array('error' => array('socket' => '', 'error' => ''), 'success' => true, 'key' => '', 'installationId' => '');
			}

			$sessSerrures = new Container('serrures');
			$sessSerrures->numeroEncodeur = $data['numeroEncodeur'];
			return new JsonModel(array('data' => $data, 'results' => $resp));
		}
	}

	private function encodeSerrures($data = [], $commandType = '')
	{
		$clesErreursTable = $this->getTableObjet('cles_erreurs');

		// DEBUT
		//Création du socket
		$errorSocket = $key = $installationId = '';

		$socket = socket_create(AF_INET, SOCK_STREAM, 0);
		if ($socket === false) {
			$errorSocket = "<pre> socket_create() a échoué : raison : " . socket_strerror(socket_last_error()) . "</pre>";
		}

		$domiciliations_config = $this->getTableObjet('domiciliation_config')->select(array('id' => 1))->current();
		//Connexion au socket
		// $result = socket_connect($socket, '193.248.53.169', 8090);
		$result = socket_connect($socket, $domiciliations_config->ip, 8090);
		if ($socket === false) {
			$errorSocket = "<pre>socket_connect() a échoué : raison : ($result)" . socket_strerror(socket_last_error($socket)) . "</pre>";
		}

		if ($commandType !== '' && $commandType === 'checkOut') {
			$roomToCheckOut = '001';
			$command = chr(2).chr(179).'CO'.chr(179).'0'.chr(179).$roomToCheckOut.chr(179).chr(3).chr(13);

			$length = strlen($command);
			$sw = socket_write($socket, $command, $length);
			if ($sw === false) {
				$errorSocket = "<pre>Impossible d'écrire dans le socket : ".socket_strerror(socket_last_error()) . "</pre>";
			}

			//Lire la réponse
			$sr = socket_read($socket, 2048);
			if ($sr === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			$sr2 = socket_read($socket, 2048);
			if ($sr2 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket : ".socket_strerror(socket_last_error()) . "</pre>";
			}

			//Fermeture du socket
			socket_close($socket);

			// Lecture du socket
			$success = false;
			$socketData = unpack('C*', $sr2);
			array_pop($socketData); // On supprime le LRC
			$responseData = '';
			foreach ($socketData as $key => $value) {
				$char = utf8_encode(chr($value)); // Récupere la valeur lisible

				if ($value == 2 || $value == 3) {
					continue;
				}
				// if ($char == '³') $response .= '|';
				else {
					$responseData .= $char;
				}
			}

			$responseData = explode('³', $responseData);
			$key = sizeof($responseData) > 3 ? $responseData[3] : '';
			$installationId = sizeof($responseData) > 4 ? $responseData[4] : '';

			$error = $clesErreursTable->select(array('code' => $responseData[1]))->current();
			if ($errorSocket != '' || $error) {
				return array('error' => array('socket' => $errorSocket, 'error' => $error), 'success' => false);
			} else {
				return array('error' => array('socket' => '', 'error' => ''), 'success' => true, 'key' => $key, 'installationId' => $installationId);
			}
		} else {
			if ($data['peripherique'] == 'encodeur') {
				$motorisedEndoders = ['E', 'R', 'T'];
				$roomsToBeOpened = ['001', '002', '003', '004'];

				// CN|1|E|001(room1)|(room2)|(room3)|(room4)|1(autorisations granted)|2(autorisations denied)|10261018|12271019|Receptionist|track1|track2|track3|
				$commandType = $data['type'] === 'p' ? 'CN' : 'CC';
				$command = chr(2).chr(179).$commandType.chr(179);
				$command .= $data['numeroEncodeur'].chr(179); // Encoder number in which the requested card will be encoded.
				$command .= $motorisedEndoders[0].chr(179);
				$command .= $roomsToBeOpened[0].chr(179); // a remplacer par le numéro de chambre
				$command .= ''.chr(179); // Second room to be opened by the card. Max. 24 characters.
				$command .= ''.chr(179); // Third room to be opened by the card. Max. 24 characters.
				$command .= ''.chr(179); // Fourth room to be opened by the card. Max. 24 characters.

				$zonesGranted = '';
				// Pour chaque zone à autoriser
				if (count($data['zones']) > 0) {
					foreach ($data['zones'] as $key => $zone) {
						$zonesGranted .= chr($zone['valeurDecimal']);
					}
				}

				$command .= $zonesGranted.chr(179); // Authorisations granted to guest.
				$command .= ''.chr(179); // Authorisations denied to guest.
				$command .= $data['startDateTime'].chr(179); // Starting date and time of the card.
				$command .= $data['expiringDateTime'].chr(179); // Expiring date and time of the card.
				$command .= ''.chr(179); // Data of the operator who makes the request. Max. 24 characters.
				$command .= ''.chr(179); // Information to be written on track #1.
				$command .= ''.chr(179); // Information to be written on track #2.
				$command .= ''.chr(179); // Information to be written on track #3.
				$command .= chr(3).chr(13);

				// echo $command;die();
				$length = strlen($command);
				$sw = socket_write($socket, $command, $length);
				if ($sw === false) {
					$errorSocket = "<pre>Impossible d'écrire dans le socket : ".socket_strerror(socket_last_error()) . "</pre>";
				}

				//Lire la réponse
				$sr = socket_read($socket, 2048);
				if ($sr === false) {
					$errorSocket = "<pre>Impossible de lire à partir du socket : ".socket_strerror(socket_last_error()) ."</pre>";
				}

				$sr2 = socket_read($socket, 2048);
				if ($sr2 === false) {
					$errorSocket = "<pre>Impossible de lire à partir du socket : ".socket_strerror(socket_last_error()) . "</pre>";
				}

				//Fermeture du socket
				socket_close($socket);

				// Lecture du socket
				$success = false;
				$socketData = unpack('C*', $sr2);
				array_pop($socketData); // On supprime le LRC
				$responseData = '';
				foreach ($socketData as $key => $value) {
					$char = utf8_encode(chr($value)); // Récupere la valeur lisible

					if ($value == 2 || $value == 3) {
						continue;
					}
					// if ($char == '³') $response .= '|';
					else {
						$responseData .= $char;
					}
				}

				$responseData = explode('³', $responseData);
				$key = sizeof($responseData) > 3 ? $responseData[3] : '';
				$installationId = sizeof($responseData) > 4 ? $responseData[4] : '';

				$error = $clesErreursTable->select(array('code' => $responseData[1]))->current();
				if ($errorSocket != '' || $error) {
					return array('error' => array('socket' => $errorSocket, 'error' => $error), 'success' => false);
				} else {
					return array('error' => array('socket' => '', 'error' => ''), 'success' => true, 'key' => $key, 'installationId' => $installationId);
				}
			} else {
				//  mettre la commande CNM si le cas futur se présente
				return array('error' => array('socket' => '', 'error' => ''), 'success' => true, 'key' => '', 'installationId' => '');
			}
		}
	}

	public function logementsAction()
	{
		$request = $this->getRequest();
		if ($request->isGet()) {
			$logementsTable = $this->getTableObjet('logements');

			$logements = $logementsTable->select(array('tampon' => 0))->toArray();
			return new JsonModel(array('logements' => $logements));
		}
	}

	public function loadmodeRdvAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$config = $this->getConfigurationTable()->getConfig(1);
		$request = $this->getRequest();
		if ($request->isGet()) {
			/*
						$listOfRdvs = $this->getEdlTable()->fetchAll()->toArray();

						date_default_timezone_set('Europe/Berlin');
						$tz = new \DateTimezone('UTC');
						$begin = new \DateTime("2017-09-22 08:45", $tz);
						$end   = new \DateTime("2017-09-22 12:00", $tz);

						$interval = \DateInterval::createFromDateString('15 min');
						$times    = new \DatePeriod($begin, $interval, $end);
						// echo $time->add($interval)->format('Y-m-d h:i:s');

						// $time = strtotime('now');
						$rdvs = array();
						foreach ($listOfRdvs as $key => $rdv) {

							//create today 10 o'clock
							$dt = \DateTime::createFromFormat('H:i', (isset($dt) && !empty($dt))?$dt->format('H:i') : '08:45');
							$dt = $dt->add(new \DateInterval('PT15M'));  // add 10 Minutes

							$resid = $this->getLogementTable()->getResidenceDeLogement($rdv['id_logement']);
							if($resid) {
								$rdv['batiment'] = $resid->batiment;
								$rdv['residence'] = $resid->residence;
								$rdv['numero'] = $resid->numero;
								$rdv['date']= date("d-m-Y")." ".$dt->format('H:i');
							}
							array_push($rdvs, $rdv);
						}
			*/
			$residenceResult = $this->getResidencesTable()->fetchByGest($gestId);
			$residences = array();
			foreach ($residenceResult as $resid) {
				$residences[$resid->id] = $resid;
			}
			$batiments = array();

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/moderdv')
			->setVariables(array('residences' => $residences, 'batiments' => $batiments, 'config' => $config ));
			//->setVariables(array('rdvs'=>$rdvs, 'locTable'=>$this->getLocatairesTable(), ));


			// $loc = $this->getLocatairesTable()->getLocataire(363);

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array('success' => true, 'htmlOP' => $htmlOutput));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function uploadAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] FILES=".json_encode($_FILES));
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			//print_r($_FILES);

			if (!is_dir(getcwd()."/public/docs/pj")) {
				mkdir(getcwd()."/public/docs/pj");
			}

			$folder = getcwd()."/public/docs/pj";
			$passer = 0;//0:pas fourni , 1:pas chargé, 2:extension non valide, 3:uploader
			$namePJ = "";

			$conf = $this->getConfigurationTable()->getConfig(1);

			if (isset($_FILES['pj']) && $_FILES['pj']['error'] == 0) {
				$passer = 1;

				$extension = pathinfo($_FILES['pj']['name'], PATHINFO_EXTENSION);
				$filename = pathinfo($_FILES['pj']['name'], PATHINFO_FILENAME);
				//if($request->getPost('nomModele')){
				//$namePJ = "pj_".$this->removeAccent($request->getPost('nomModele'))."_".date('Y-m-d-his').".".$extension;
				//}else{
				$namePJ = $this->removeAccent($filename).".".$extension;
				//}
				if (file_exists($folder.'/'.$namePJ)) {
					$namePJ = $this->removeAccent($filename)."_".date('His').".".$extension;
					if (file_exists($folder.'/'.$namePJ)) {
						$namePJ = $this->removeAccent($filename)."_".date('YmdHis').".".$extension;
					}
				}
				if($conf->extensionPJMails) {
					$allowed = explode(',', $conf->extensionPJMails);
				} else {
					$allowed = array('pdf');
				}

				if (!in_array(strtolower($extension), $allowed)) {
					$passer = 2;
				} else {

					//unlink($folder.'/'.$conf->logo);

					if (move_uploaded_file($_FILES['pj']['tmp_name'], $folder.'/'.$namePJ)) {
						//upload réussi

						$passer = 3;
					}
				}
			}


			$msg = "";
			switch ($passer) {
				case 0: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 1: $msg = "<span class='error red'>Erreur upload</span>";
					break;
				case 2: $msg = "<span class='error red'>Erreur extension (seulement pdf autorisé)</span>";
					break;
				case 3: $msg = "<span class='success green'>Fichier chargé</span>";
					break;
			}


			$view = new JsonModel(array(
						'success' => true,
						'passer' => $passer,
						'msg' => $msg,
						'pjname' => $namePJ,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function deletepjAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idModele = $request->getPost('id');
			//on verifie si le idModele est composé : si oui c'est un modele campagne
			$idModeleCampArr = explode('-', $idModele);
			$idCampagne = $idModeleParent = 0;
			if (sizeof($idModeleCampArr) > 1) {
				$idModele = $idModeleCampArr[0];
				$idCampagne = $idModeleCampArr[1];
			}
			$deleted = 0;

			if ($idModele > 0) {
				if ($idCampagne > 0) {
					$mdl = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
					$this->getModelescampagneTable()->updateModele(array('idModele' => $idModele, 'idCampagne' => $idCampagne), array('pj' => ''));
				} else {
					$mdl = $this->getModelesmailTable()->getModele($idModele);
					$this->getModelesmailTable()->updateModele($idModele, array('pj' => ''));
				}
				$this->deleteFile(getcwd()."/public/docs/pj/".$mdl->pj);
				$deleted = 1;
				$msg = utf8_encode("<span class='success green'>Pièce jointe supprimée</span>");
			} else {
				$msg = utf8_encode("<span class='red'>Modèle introuvable</span>");
			}

			$view = new JsonModel(array(
						'success' => true,
						'msg' => $msg,
						'deleted' => $deleted,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function deletepjfileAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$file = $request->getPost('filename');
			$idModele = $request->getPost('idModele', 0);
			if ($idModele) {
				//on verifie si le idModele est composé : si oui c'est un modele campagne
				$idModeleCampArr = explode('-', $idModele);
				$idCampagne = $idModeleParent = 0;
				if (sizeof($idModeleCampArr) > 1) {
					$idModele = $idModeleCampArr[0];
					$idCampagne = $idModeleCampArr[1];
				}
				$deleted = 0;

				if ($idModele > 0) {
					if ($idCampagne > 0) {
						$mdl = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
						$this->getModelescampagneTable()->updateModele(array('idModele' => $idModele, 'idCampagne' => $idCampagne), array('pj' => ''));
					} else {
						$mdl = $this->getModelesmailTable()->getModele($idModele);
						$this->getModelesmailTable()->updateModele($idModele, array('pj' => ''));
					}
					$this->deleteFile(getcwd()."/public/docs/pj/".$file);
					$deleted = 1;
					$msg = utf8_encode("<span class='success green'>Pièce jointe supprimée</span>");
				} else {
					$msg = utf8_encode("<span class='red'>Modèle introuvable</span>");
				}
			} else {
				$this->deleteFile(getcwd()."/public/docs/pj/".$file);
			}

			$msg = ("<span class='success green'>Document supprime</span>");

			$view = new JsonModel(array(
						'success' => true,
						'msg' => $msg,
						'deleted' => $deleted,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function saveAction()
	{
		$form = new MailForm();
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$msg = "";
		$maj = 1; //maj du type et nom, interdit pour les mail auto

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

			$idModele = $request->getPost('id');
			$isResa = $request->getPost('isResa');
			$idCategorie = (int) $request->getPost('idCategorieFiltre');
			$modeListe = $request->getPost('modeListe');

			$post_nomFrom = $request->getPost('nomFrom');
			$post_emailFrom = $request->getPost('emailFrom');
			$post_objet = $request->getPost('objet');
			$post_nomModele = $request->getPost('nomModele');
			$post_idType = $request->getPost('idType');
			$post_langue = $request->getPost('langue');
			$post_corps = $request->getPost('corps');
			$post_idProfile = $request->getPost('idProfile');
			$post_idListePJ = $request->getPost('idListePJ', array());
			$post_idProfileDest = $request->getPost('idProfileDest');
			$post_idProfileCopie = $request->getPost('idProfileCopie');
			$post_idProfileCopieCachee = $request->getPost('idProfileCopieCachee');

			$post_idsModelesDocs = $request->getPost('idsModelesDocs', '');
			$post_idTypeSuivis = $request->getPost('idTypeSuivis', null);
			$post_idCatalogue = $request->getPost('idCatalogue', null);

			$fromController = $request->getPost('fromController');

			$callType = $request->getPost('callType', '');
			$typeListeFact = $request->getPost('typeListeFact', '');//Mode facture(facturesmois)pour charger le modèle facture par défaut

			//print_r($request->getPost());exit();

			//on verifie si le idModele est composé : si oui c'est un modele campagne
			$idModeleCampArr = explode('-', $idModele);
			$idCampagne = $idModeleParent = 0;
			if (sizeof($idModeleCampArr) > 1) {
				$idModeleParent = $idModeleCampArr[0];
				$idCampagne = $idModeleCampArr[1];
			}

			if (!$post_idType) {
				$post_idType = 1;//par defaut type public
			}
			if ($idCampagne > 0) {
				$notValide = !$post_nomFrom || !$post_emailFrom || !$post_objet || !$post_corps;
			} else {
				$notValide = !$post_nomFrom || !$post_emailFrom || !$post_objet || !$post_nomModele || !$post_langue || !$post_corps || !$post_idProfile;
			}
			if ($notValide) {
				if ($idCampagne > 0) {
					$msgErreur = "Veuillez remplir tout les champs en rouge(Nom Emetteur, Email emetteur, Objet et Corps du mail)";
				} else {
					$msgErreur = "Veuillez remplir tout les champs en rouge(Nom Emetteur, Email emetteur, Objet, Nom du mail, Profile, Langue et Corps du mail)";
				}
				$view = new JsonModel(array(
						'success' => false,
						'id' => $idModele,
						'maj' => false,
						  'msg' => $msgErreur,

				));

				$view->setTerminal(true);
				return $view;
			}


			//etats de liste public,private
			$tableObj3 = new Tables('type_email', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$types1 = $tableObj3->getTable()->select(array('auto' => '1'));
			$types = $tableObj3->getTable()->select(array('auto' => '1'));
			$typesOption = array();
			foreach ($types1 as $t) {
				$typesOption[$t->id] = $t->type;
			}

			$form->get('idType')->setAttribute('options', $typesOption);

			## categories
			$catsRows = $this->getTableObjet('categorie_mail')->select(array('deleted' => 0));
			$catOptions = array();
			foreach ($catsRows as $row) {
				$catOptions[$row->id] = $row->categorie;
			}
			$form->get('idCategorie')->setAttribute('options', $catOptions);
			$form->get('idCategorieFiltre')->setAttribute('options', $catOptions);
			$form->get('idCategorieFiltre')->setValue($idCategorie);

			$modeles = $this->getModelesmailTable()->fetchAll($idProfile, $idCategorie);
			$modelesOption = array();
			foreach ($modeles as $m) {
				//on affiche les listes public
				$catName = $m->categorie ? $m->categorie : 'Sans catégorie';
				$typeName = $m->idType && $typesModeles[$m->idType] != "" ? $typesModeles[$m->idType] : 'Sans type';
				$opt = array('label' => '('.$catName.')'.$m->nomModele." (".$typeName.")", 'value' => $m->id,
							'attributes' => array('data-type' => $m->idType, 'data-langue' => $m->langue, 'data-objet' => $m->objet),
							);

				if ($m->idType != '2') {
					$modelesOption[] = $opt;
				} elseif ($m->idUser == $gestId) {
					$modelesOption[] = $opt;
				}
			}

			$form->get('idModele')->setAttribute('options', $modelesOption);
			$form->get('idModele')->setValue($idModele);

			$langues = $this->getLangues();
			$form->get('langue')->setAttribute('options', $langues);
			$form->get('langueFiltre')->setAttribute('options', $langues);

			$modele = null;
			if ($idModele > 0 || $idCampagne > 0) {
				if ($idCampagne > 0) {
					$modele = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
					$modeleOld = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
					//on recup, le idType, langue, idUser et idCategorie du modele parent
					$modeleParent = $this->getModelesmailTable()->getModele($idModeleParent);
					if ($modeleParent) {
						$modele->idType = $modeleParent->idType;
						$modele->langue = $modeleParent->langue;
						$modele->idUser = $modeleParent->idUser;
						$modele->idCategorie = $modeleParent->idCategorie;
						$modele->id = $idModeleParent.'-'.$idCampagne;
						$modele->nomModele = $modeleParent->nomModele;

						$modeleOld->idType = $modeleParent->idType;
						$modeleOld->langue = $modeleParent->langue;
						$modeleOld->idUser = $modeleParent->idUser;
						$modeleOld->idCategorie = $modeleParent->idCategorie;
						$modeleOld->id = $idModeleParent.'-'.$idCampagne;
						$modeleOld->nomModele = $modeleParent->nomModele;
					}
				} else {
					$modele = $this->getModelesmailTable()->getModele($idModele);
					$modeleOld = $this->getModelesmailTable()->getModele($idModele);
				}
				$form->bind($modele);

				//on fait la maj
				if ($idModele > 0 && !$idCampagne) {
					$form->setInputFilter($modele->getInputFilter());
					$form->setData($request->getPost());
					//if($form->isValid()){
					//$pjs = substr($request->getPost('pjName'), 0,-1);
					if ($request->getPost('pjName')) {
						$pjs = explode('|', $request->getPost('pjName'));


						if ($modeleOld->pj != $request->getPost('pjName')) {
							if ($modeleOld->pj != "") {
								$this->deleteFile(getcwd()."/public/docs/pj/".$modeleOld->pj);
							}
						}
					}
					$modele->exchangeArray($request->getPost());
					//print_r($modele);
					if (!$modele->idType) {
						//$modele->idType = $modeleOld->idType;
						$modele->idType = 1;
					}

					$modele->pj = $request->getPost('pjName');
					$this->getModelesmailTable()->saveModele($modele);


					$msg = "Modification effectuée avec succès";

					//save logs
					$logs = new Logs();
					$diff = $logs->arrayDiff($modeleOld, $modele);
					$operation = "Modification modèle $idModele ".$modele->nomModele.", par : ".$user->getDisplayName();
					$dataLog = array('operation' => $operation,
									'dateOperation' => date('Y-m-d H:i:s'),
									'dataBefore' => $diff['before'],
									'dataAfter' => $diff['after'],
									'idGestionnaire' => $gestId,
									'tableName' => 'modeles_email');
					$logs->exchangeArray($dataLog);
					$this->getLogsTable()->saveLogs($logs);
					//}
				} elseif ($idCampagne > 0 && $idModeleParent > 0) {
					// modele campagne
					$modeleCamp = $this->getModelescampagneTable()->getModele($idCampagne, $idModeleParent);
					$oldModeleCamp = clone $modeleCamp;
					$form->setInputFilter($modele->getInputFilter());
					$form->setData($request->getPost());

					if ($request->getPost('pjName')) {
						$pjs = explode('|', $request->getPost('pjName'));


						if ($modeleOld->pj != $request->getPost('pjName')) {
							if ($modeleOld->pj != "") {
								$this->deleteFile(getcwd()."/public/docs/pj/".$modeleOld->pj);
							}
						}
					}
					$modeleCamp->exchangeArray($request->getPost());
					$modeleCamp->idCampagne = $idCampagne;
					$modeleCamp->idModele = $idModeleParent;

					$modeleCamp->pj = $request->getPost('pjName');
					$this->getModelescampagneTable()->saveModele($modeleCamp);


					$msg = "Modification effectuée avec succès";

					//save logs
					$logs = new Logs();
					$modeleParent = $this->getModelesmailTable()->getModele($idModeleParent);
					$diff = $logs->arrayDiff($oldModeleCamp, $modeleCamp);
					$operation = "Modification modèle campagne $idModeleParent ".$modeleParent->nomModele.", par : ".$user->getDisplayName();
					$dataLog = array('operation' => $operation,
									'dateOperation' => date('Y-m-d H:i:s'),
									'dataBefore' => $diff['before'],
									'dataAfter' => $diff['after'],
									'idGestionnaire' => $gestId,
									'tableName' => 'modeles_email_campagne');
					$logs->exchangeArray($dataLog);
					$this->getLogsTable()->saveLogs($logs);
				}
			} else {
				//ajout

				$modele = new Modelesmail();
				$form->setInputFilter($modele->getInputFilter());
				$form->setData($request->getPost());

				/*$data = array_merge_recursive(
				 $this->getRequest()->getPost()->toArray(),
				 $this->getRequest()->getFiles()->toArray()
				 );
				 $form->setData($data);*/


				$modele->exchangeArray($request->getPost());
				$modele->idUser = $gestId;
				$modele->idListe = 1;
				if (!$modele->idType) {
					$modele->idType = 1;// type public par defaut
				}
				$modele->pj = $request->getPost('pjName');

				//print_r($modele);

				$idModele = $this->getModelesmailTable()->saveModele($modele);
				$msg = "Ajout effectuée avec succès";

				//save logs
				$logs = new Logs();
				$operation = "Ajout modèle ".$modele->nomModele.", par : ".$user->getDisplayName();
				$dataLog = array('operation' => $operation,
								'dateOperation' => date('Y-m-d H:i:s'),
								'dataBefore' => array(),
								'dataAfter' => $modele,
								'idGestionnaire' => $gestId,
								'tableName' => 'modeles_email');
				$logs->exchangeArray($dataLog);
				$this->getLogsTable()->saveLogs($logs);

			}

			## maj profiles
			if ($post_idProfile && !$idCampagne) {
				//on supprime
				$this->getTableObjet('modeles_email_profile')->delete(array('idModele' => $idModele));
				foreach ($post_idProfile as $idProfile) {
					// puis on ajoute
					$this->getTableObjet('modeles_email_profile')->insert(array('idModele' => $idModele, 'idProfile' => $idProfile));
				}
			}

			## maj profiles dest/copie/copie cachée
			if(($post_idProfileDest || $post_idProfileCopie || $post_idProfileCopieCachee) && !$idCampagne) {
				$this->getTableObjet('modeles_email_profile_envois')->delete(array('idModele' => $idModele));
			}
			if ($post_idProfileDest && !$idCampagne) {
				foreach ($post_idProfileDest as $idProfile) {
					$this->getTableObjet('modeles_email_profile_envois')->insert(array('idModele' => $idModele, 'idProfile' => $idProfile, 'typeEnvois' => 'dest'));
				}
			}

			if ($post_idProfileCopie && !$idCampagne) {
				foreach ($post_idProfileCopie as $idProfile) {
					$this->getTableObjet('modeles_email_profile_envois')->insert(array('idModele' => $idModele, 'idProfile' => $idProfile, 'typeEnvois' => 'copie'));
				}
			}

			if ($post_idProfileCopieCachee && !$idCampagne) {
				foreach ($post_idProfileCopieCachee as $idProfile) {
					$this->getTableObjet('modeles_email_profile_envois')->insert(array('idModele' => $idModele, 'idProfile' => $idProfile, 'typeEnvois' => 'copieCachee'));
				}
			}

			## maj export liste comme PJ
			if (isset($post_idListePJ) && !$idCampagne) {
				//on supprime
				$tableMEL = $this->getTableObjet('modeles_email_listes');
				$tableMEL->delete(array('idModele' => $idModele));
				foreach ($post_idListePJ as $idListePJ) {
					// puis on ajoute
					$modeListe = '';
					$idListe = '';
					if(strpos($idListePJ, '|') !== false) {
						$idListeArr = explode("|", $idListePJ);
						//on supprime les element vide
						$idListeArr = array_filter($idListeArr);
						$modeListe = !empty($idListeArr[0]) ? $idListeArr[0] : '';
						$idListe = !empty($idListeArr[1]) ? $idListeArr[1] : '';
					}
					if($idListe && $modeListe) {
						$tableMEL->insert(array('idModele' => $idModele, 'idListe' => $idListe, 'modeListe' => $modeListe));
					}
				}
			}

			## maj des modèles de docs affecter au modèle mail
			if (isset($post_idsModelesDocs)) {
				if($idCampagne){
					$tableMD = $this->getTableObjet('modeles_email_modeles_docs_camp');
					$tableMD->delete(array('idModeleMail' => $idModeleParent,'idCampagne'=>$idCampagne));
				}else{
					$tableMD = $this->getTableObjet('modeles_email_modeles_docs');
					$tableMD->delete(array('idModeleMail' => $idModele));
				}
				
				
				$idsModelesArr = array_filter(explode('-', $post_idsModelesDocs));
				if (!empty($idsModelesArr)) {
					foreach ($idsModelesArr as $idModeleDoc) {
						if($idCampagne){
							$whereMD = array('idModeleDoc' => $idModeleDoc, 'idModeleMail' => $idModeleParent,'idCampagne'=>$idCampagne);
						}else{
							$whereMD = array('idModeleDoc' => $idModeleDoc, 'idModeleMail' => $idModele);
						}
						$rowMD = $tableMD->select($whereMD)->current();
						if(!$rowMD){
							$tableMD->insert($whereMD);
						}
					}
				}
			}

			## maj modele animation
			if($post_idTypeSuivis && $post_idCatalogue) {
				$tableMA = $this->getTableObjet('modeles_email_animation');
				$tableMA->delete(array('idModele' => $idModele));
				$tableMA->insert(array('idModele' => $idModele, 'idTypeSuivis' => $post_idTypeSuivis, 'idCatalogue' => $post_idCatalogue));
			}

			## maj de la liste des email

			$emailFrom = $this->getTableObjet('email_liste')->select(array('email' => $modele->emailFrom))->current();
			if ($modele->emailFrom && !$emailFrom) {
				$this->getTableObjet('email_liste')->insert(array('email' => $modele->emailFrom));
			}

			$emailsCopie = explode(',', $modele->emailCopie);
			foreach ($emailsCopie as $email):
				$emailCopie = $this->getTableObjet('email_liste')->select(array('email' => $email))->current();
				if (!$emailCopie) {
					$this->getTableObjet('email_liste')->insert(array('email' => $email));
				}
			endforeach;

			$emailsCopieCachee = explode(',', $modele->emailCopieCachee);
			foreach ($emailsCopieCachee as $email):
				$emailCopieCachee = $this->getTableObjet('email_liste')->select(array('email' => $email))->current();
				if (!$emailCopieCachee) {
					$this->getTableObjet('email_liste')->insert(array('email' => $email));
				}
			endforeach;

			if ($modele->emailDest) {
				$emailsDest = explode(',', $modele->emailDest);
				foreach ($emailsDest as $email):
					$emailDest = $this->getTableObjet('email_liste')->select(array('email' => $email))->current();
					if (!$emailDest) {
						$this->getTableObjet('email_liste')->insert(array('email' => $email));
					}
				endforeach;
			}

			if ($modele->emailReplyTo) {
				$emailsReplyTo = explode(',', $modele->emailReplyTo);
				foreach ($emailsReplyTo as $email):
					$emailReplyTo = $this->getTableObjet('email_liste')->select(array('email' => $email))->current();
					if (!$emailReplyTo) {
						$this->getTableObjet('email_liste')->insert(array('email' => $email));
					}
				endforeach;
			}

			$params = array('idModele' => $idModele, 'idCategorie' => $idCategorie, 'modeListe' => $modeListe, 'isResa' => $isResa, 'fromController' => $fromController, 'typeListeFact' => $typeListeFact, 'callType' => $callType);
			extract($this->loadModelesMailView($params));

			/*****
			//liste des emails
			$result = $this->getTableObjet('email_liste')->select();
			$emails = array();
			foreach($result as $row){
				$emails[] = $row;
			}


			$modeles = $this->getModelesmailTable()->fetchAll($idProfile,$idCategorie);
			$modelesOption = array();
			foreach($modeles as $m){
				//on affiche les listes public
				$catName = $m->categorie ? $m->categorie : 'Sans catégorie';
				$typeName = $m->idType && $typesModeles[$m->idType] != "" ? $typesModeles[$m->idType] : 'Sans type';
				$opt = array('label'=>'('.$catName.')'.$m->nomModele." (".$typeName.")", 'value'=>$m->id,
							'attributes'=>array('data-type'=>$m->idType,'data-langue'=>$m->langue)
							);
				if($m->idType != '2'){
					$modelesOption[] = $opt;
				}elseif($m->idUser == $gestId){
					$modelesOption[] = $opt;
				}
			}

			$modele = $this->getModelesmailTable()->getModele($idModele);


			foreach($types as $t){
				$typesOption[$t->id] = $t->type;
			}

			$form->get('idType')->setAttribute('options',$typesOption);

			$form->get('idModele')->setAttribute('options',$modelesOption);
			$form->get('idModele')->setValue($idModele);


			$form->bind($modele);

			//pour les mail auto
			if($modele->idType > 2){
				$maj = 0;
				$isResa = true;
			}

			## profiles
			$profilesResult = $this->getTableObjet('user_role')->select();
			$profiles = array();
			foreach($profilesResult as $profile){
				if($profile->role_id != "guest"){
					//selected des profiles choisis
					$pRow = $this->getTableObjet('modeles_email_profile')->select(array('idModele'=>$idModele,'idProfile'=>$profile->role_id))->current();
					if($pRow){
						$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name, 'selected' => 'selected');
					}else{
						$profiles[] = array('value' => $profile->role_id, 'label' => $profile->role_name);
					}
				}
			}
			$form->get('idProfile')->setAttribute('options',$profiles);

			extract($this->getModeleMailChamps());

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modele')
			->setVariables(array(
					'id' => $idModele,
					'form' => $form,
					'msg' => $msg,
					'modele' => $modele,
					'isResa' => $isResa,
					//'theme1' => $this->getThemeFields(1),
					//'theme2' => $this->getThemeFields(2),
					//'theme3' => $this->getThemeFields(3),
					//'theme4' => $this->getThemeFields(4),
					'emails' => $emails,
					'docsTable'=>$this->getDocumentTable(),
					'written'=>($_SESSION['USERDROIT']['mode-input-mails'] == 'W'),
					'modeListe'=>$modeListe,
					'catRows' => $catRows,
					'allChamps' => $allChamps,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);
			*/
			$pametres_mail = null;
			if($post_idType > 2) {
				$pametres_mail = $this->getTableObjet('pametres_mail')->select(array('idTypeEmail' => $post_idType))->current();
			}
			if ($idModele) {
				$pametres_mail_modele = $this->getTableObjet('pametres_mail')->select(array('idModele' => $idModele))->current();
				if ($pametres_mail_modele) {
					$pametres_mail = $pametres_mail_modele;
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						'id' => $idModele,
						'maj' => $maj,
						  'htmlOP' => $htmlOutput,
						  'idCampagne' => $idCampagne,
						  'pametres_mail' => $pametres_mail,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function loaddocsAction()
	{
		$request = $this->getRequest();
		$msg = "";
		if ($request->isXmlHttpRequest()) {
			$type = $request->getPost('type');
			$idModele = $request->getPost('idModele');
			if ($type == "WLDoc") {
				$docs = $this->getDocumentTable()->getAll();

				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/docs')
				->setVariables(array(
						'docs' => $docs,

				));
			} else {

				/*$modeles = $this->getModelesmailTable()->fetchAll();
				$docs = array();
				foreach($modeles as $row){
					if($row->id != $idModele){
						if($row->pj){
							$pjs = explode('|', $row->pj);
							foreach ($pjs as $file) {
								if($file!="" && file_exists(getcwd().'/public/docs/pj/'.$file)){
									if(!in_array($file, $docs)){

										$docs[] = $file;

									}
								}
							}
						}
					}
				}*/
				//on cherche les modèles de documents
				$where = array('active' => 1, 'imprimableEnLot' => 1, 'typeModele' => 'reservation');
				$modeles = $this->getTableObjet('type_modeles_docs')->select($where);

				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/modeledoc')
				->setVariables(array(
						'modeles' => $modeles,
						'idModele' => $idModele,
						'written' => ($_SESSION['USERDROIT']['mode-input-mails'] == 'W'),
				));
			}


			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function deletemodeleAction()
	{
		//$form = new MailForm();
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$msg = "";
		$allowed = 0;

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			//$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;


			$idModele = $request->getPost('id');
			$isResa = $request->getPost('isResa');
			$idCategorie = (int) $request->getPost('idCategorie');
			$modeListe = $request->getPost('modeListe');
			$fromController = $request->getPost('fromController');
			$callType = $request->getPost('callType');

			$idModeleCampArr = explode('-', $idModele);
			$idCampagne = $idModeleParent = 0;
			if (sizeof($idModeleCampArr) > 1) {
				$idModeleParent = $idModeleCampArr[0];
				$idCampagne = $idModeleCampArr[1];
			}

			$modele = null;

			if ($idCampagne > 0 && $idModeleParent > 0) {
				$modeleCamp = $this->getModelescampagneTable()->getModele($idCampagne, $idModele);
				$this->getModelescampagneTable()->deleteModele(array('idModele' => $idModele, 'idCampagne' => $idCampagne));
				## save logs
				$logs = new Logs();
				$modele = $this->getModelesmailTable()->getModele($idModeleParent);
				$operation = "Suppression modèle campagne $idModeleParent ".$modele->nomModele.", par : ".$user->getDisplayName();
				$dataLog = array('operation' => $operation,
								'dateOperation' => date('Y-m-d H:i:s'),
								'dataBefore' => $modeleCamp,
								'dataAfter' => array(),
								'idGestionnaire' => $gestId,
								'tableName' => 'modeles_email_campagne');
				$logs->exchangeArray($dataLog);
				$this->getLogsTable()->saveLogs($logs);
			} elseif ($idModele > 0) {
				$modele = $this->getModelesmailTable()->getModele($idModele);
				$this->getModelesmailTable()->deleteModele($idModele);
				//on supprime les profiles associé
				$this->getTableObjet('modeles_email_profile')->delete(array('idModele' => $idModele));
				$this->getTableObjet('modeles_email_listes')->delete(array('idModele' => $idModele));
				$msg = "Modèle supprimé";
				## save logs
				$modele = $this->getModelesmailTable()->getModele($idModele);
				$logs = new Logs();
				$operation = "Suppression modèle $idModele ".$modele->nomModele.", par : ".$user->getDisplayName();
				$dataLog = array('operation' => $operation,
								'dateOperation' => date('Y-m-d H:i:s'),
								'dataBefore' => $modele,
								'dataAfter' => array(),
								'idGestionnaire' => $gestId,
								'tableName' => 'modeles_email');
				$logs->exchangeArray($dataLog);
				$this->getLogsTable()->saveLogs($logs);
			}

			$params = array('idModele' => 0, 'idCategorie' => $idCategorie, 'modeListe' => $modeListe, 'isResa' => $isResa, 'fromController' => $fromController, 'callType' => $callType);
			extract($this->loadModelesMailView($params));


			$view = new JsonModel(array(
						'success' => true,
						'id' => 0,
						'maj' => 1,
						  'htmlOP' => $htmlOutput,
						  'idCampagne' => $idCampagne,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function addAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {

			##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : POST=".json_encode($request->getPost()));

			$idListe = $request->getPost('idListe');//-1 : ajout, >0 : maj, 0 : ne faire rien
			$jsonDpDatatableState = $request->getPost('jsonDpDatatableState', '');

			$mode = 'resa';
			$jsonResaDatatableState	= json_decode($request->getPost('jsonResaDatatableState'), 1);

			if ($jsonDpDatatableState != '') {
				$mode = 'dp';
				$jsonResaDatatableState	= json_decode($request->getPost('jsonDpDatatableState'), 1);
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe jsonResaDatatableState=".json_encode($jsonResaDatatableState));

			$liste = new Listes();
			$liste->nom = $request->getPost('liste_name');
			$liste->idEtat = !empty($request->getPost('idEtat')) ? $request->getPost('idEtat') : 2;
			$liste->idType = $request->getPost('idTypeListe');
			$liste->idCategorie = $request->getPost('idCategorieListe');
			$liste->idUser = $gestId;
			$flag = $request->getPost('flag', null);
			if ($flag) {
				$liste->flag = 'planning';
			}

			$indicateur = $request->getPost('indicateur', 0);
			if ($indicateur) {
				$indicateur = 1;
			}
			$liste->indicateur = $indicateur;

			$isStats = 0;
			if ($request->getPost('stats') == "on") {
				$isStats = 1;
			} elseif ($request->getPost('stats') == 1) {
				$isStats = 1;
			}
			$liste->stats = $isStats;

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe liste_name=".$liste->nom." idEtat=".$liste->idEtat." idType=".$liste->idType." gestId=".$liste->idUser);

			if ($idListe == 0) {
				//redirection
				return $this->redirect()->toRoute('zfcadmin/liste');
			}

			if ($idListe > 0 && !$jsonResaDatatableState['filter']) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe jsonResaDatatableStateFilter ne peut pas etre vide");
				//redirection
				return $this->redirect()->toRoute('zfcadmin/liste');
			}

			if ($idListe == '-1') {
				//ajout
				if ($mode == 'dp') {
					$table = $this->getTableObjet('domiciliations_listes');
					$data = array(
						'nom'  => $liste->nom,
						'idUser'  => $liste->idUser,
						'idEtat'  => $liste->idEtat,
						'idType'  => $liste->idType,
						'stats'  => $liste->stats,
						'indicateur'  => $liste->indicateur,
						'idCategorie'  => $liste->idCategorie,
					);
					$id = (int) $liste->id;
					if ($id == 0) { // si la liste n'existe pas
						$table->insert($data);
					}

					$idListe = $table->lastInsertValue;
				} else {
					$idListe = $this->getListesTable()->saveListe($liste);
				}
			}

			$oldChampsListe = null;
			$oldChampsNb	= 0;

			if ($idListe > 0) {
				// DELETE THEN INSERT PROFILES
				if ($profiles = $request->getPost('idProfile')) {
					if ($mode == 'dp') {
						$tableObj_liste_profile = new Tables('domiciliations_liste_profile', $adapter);
					} else {
						$tableObj_liste_profile = new Tables('liste_profile', $adapter);
					}

					$tableObj_liste_profile->getTable()->delete(array('idListe' => $idListe));


					## Ajout des profils si liste non privée
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($liste->idEtat != "1" && $profiles) {
						foreach ($profiles as $idProfile) {
							$tableObj_liste_profile->getTable()->insert(array('idListe' => $idListe, 'idProfile' => $idProfile));
						}
					}
				}

				//update Liste
				$liste->id = $idListe;

				if ($mode == 'dp') {
					$table = $this->getTableObjet('domiciliations_listes');
					$data = array(
						'nom'  => $liste->nom,
						'idUser'  => $liste->idUser,
						'idEtat'  => $liste->idEtat,
						'idType'  => $liste->idType,
						'stats'  => $liste->stats,
						'indicateur'  => $liste->indicateur,
						'idCategorie'  => $liste->idCategorie,
					);

					// on vérifie si la liste existe déjà
					$listExist = $this->getTableObjet('domiciliations_listes')->select(array('id' => $liste->id))->current();
					if ($listExist) {
						$table->update($data, array('id' => $liste->id));
					}
				} else {
					$this->getListesTable()->saveListe($liste);
					//on change le nom dans le dashboard
					$dataDashbord = $this->getDashboardTable()->fetchByUserid($gestId);
					if ($dataDashbord) {
						$dataDashbord->blocks = $dataDashbord->blocks ? json_decode($dataDashbord->blocks, true) : [];
						$dataDashbord->elements = $dataDashbord->elements ? json_decode($dataDashbord->elements, true) : [];

						foreach ($dataDashbord->blocks as $index => $block) {
							if ($block['type'] == 'liste') {
								$listeSavedTitle = $block['title'];
								$listeBdd = $liste;
								if ($listeBdd) {
									if ($listeSavedTitle != $listeBdd->nom) {
										//on prend le nom de la liste saved en bdd si différent
										$dataDashbord->blocks[$index]['title'] = $listeBdd->nom;
									}
								}
							}
						}

						foreach ($dataDashbord->elements as $i => $rows) {
							foreach ($rows as $index => $elem) {
								if ($elem['type'] == 'liste') {
									$listeSavedTitle = $elem['title'];
									$listeBdd = $liste;
									if ($listeBdd) {
										if ($listeSavedTitle != $listeBdd->nom) {
											//on prend le nom de la liste saved en bdd si différent
											$dataDashbord->elements[$i][$index]['title'] = $listeBdd->nom;
										}
									}
								}
							}
						}

						$blocks = json_encode($dataDashbord->blocks);
						$elements = json_encode($dataDashbord->elements);
						$data = array(
							'blocks' => $blocks,
							'elements' => $elements,
							'userid' => $gestId,
						);
						$this->getDashboardTable()->save($data);
					}
				}
			}

			## save liste state
			## ~~~~~~~~~~~~~~~~
			$tableObj_liste_state = new Tables('liste_state', $adapter);
			if ($mode == 'dp') {
				$tableObj_liste_state = new Tables('domiciliations_state', $adapter);
			}

			$row		= $tableObj_liste_state->getTable()->select(array('idListe' => $idListe))->current();
			$newData        = json_encode($jsonResaDatatableState);
			if ($row) {
				## La liste existe déjà => MAJ
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$tableObj_liste_state->getTable()->update(array('data' => $newData), array('idListe' => $idListe));
				$operation      = "Modif";
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe update oldData=".$row->data);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe update newData=$newData");
			} else {
				## La liste n'existe pas => Insert
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$tableObj_liste_state->getTable()->insert(array('idListe' => $idListe, 'data' => $newData));
				$operation      = "Ajout";
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe insert newData=$newData");
			}

			$tableName = 'liste_state';
			//sauver dans les logs
			$logs = new Logs();

			if ($mode == 'dp') {
				$tableName = 'domiciliations_state';
				$list = $this->getTableObjet('domiciliations_listes')->select(array('id' => (int) $idListe))->current();
			} else {
				$list = $this->getListesTable()->getListe($idListe);
			}

			$operation .= " de l etat de la liste : ".$list->nom.", par : ".$user->getDisplayName();
			$dataLog = array('operation' => $operation,
							'dateOperation' => date('Y-m-d H:i:s'),
							'dataBefore' => $row->data,
							'dataAfter' => $jsonResaDatatableState,
							'idGestionnaire' => $gestId,
							'tableName' => $tableName);

			$logs->exchangeArray($dataLog);
			$this->getLogsTable()->saveLogs($logs);

			$allListes = $this->getListesTable()->fetchAll($mode, $adapter);
			$allowedListe = array();
			$idDemande = "";

			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
			$allListes = $mode == 'dp' ? $this->getListesDpByProfile($idProfile) : $this->getListesTable()->fetchAllByProfile($idProfile, $mode, $adapter);
			$allowedListe = array();
			foreach ($allListes as $liste) {
				//on affiche les listes public
				$nom = $liste->nom;
				if ($liste->type) {
					$nom .= ' ('.$liste->type.')';
				}

				if ($liste->idType == '1') {
					$idDemande = $liste->id;
				}

				if ($liste->idEtat == '2') {
					$allowedListe[$liste->id] = $nom;
				} elseif ($liste->idUser == $gestId) {
					$allowedListe[$liste->id] = $nom;
				}
			}
			if ($mode == 'dp') {
				## on y ajoute les liste privée
				$privateListes = $this->getListesTable()->fetchAllPrivate($gestId, 'dp', $adapter);
				if ($privateListes) {
					foreach ($privateListes as $liste) {
						$l = (object)$liste;
						$allowedListe[$l->id] = $l->nom;
					}
				}
				if ($list->idType) {
					$typeL = $this->getTableObjet('type_domiciliations')->select(array('id' => $list->idType))->current();
					if ($typeL) {
						$list->nom .= ' ('.$typeL->type.')';
					}
				}
			} else {
				$privateListes = $this->getListesTable()->fetchAllPrivate($gestId);
				if ($privateListes) {
					foreach ($privateListes as $liste) {
						$l = (object)$liste;
						$allowedListe[$l->id] = $l->nom;
					}
				}
			}


			asort($allowedListe);

			$view = new JsonModel(array(
				'success' => true,
				'liste' => $list,
				'allListes' => $allowedListe,
				'idListeDemande' => $idDemande,
				'msg' => utf8_encode("Liste bien enregistré"),
			));

			$view->setTerminal(true);
			return $view;
		}
		return $this->redirect()->toRoute('zfcadmin/liste');
	}

	public function modeleImportExcelAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$success = false;
			$msg = '';

			$post = $request->getPost();
			$nomModele = $post->nomModele;
			$idListe = $post->idListeModele;
			$modeListeModele = $post->modeListeModele;
			$nomFile = str_replace(' ', '_', $nomModele);

			$idModeleReplace = $post->idModeleReplace;

			$tableListes = 'listes';
			if (strtolower($modeListeModele) == 'dp') {
				$tableListes = 'dp_listes';
			}

			if (!is_dir(getcwd()."/public/docs/modeles/statsListes")) {
				mkdir(getcwd()."/public/docs/modeles/statsListes");
			}

			$path = getcwd()."/public/docs/modeles/statsListes/";

			if (isset($_FILES['excelFile']['name'])) {
				$ext = pathinfo($_FILES['excelFile']['name'], PATHINFO_EXTENSION);
				if ($ext == "xlsx" || $ext == "xlsm") {
					$file = $nomFile.".".$ext;
					$pathFile = $path.$file;
					if (move_uploaded_file($_FILES['excelFile']['tmp_name'], $pathFile)) {
						if ($idModeleReplace > 0) {
							$modeleStats = $this->getTableObjet('stats_modeles')->update(array('nom' => $nomModele, 'nomFile' => $file), array('id' => $idModeleReplace));
						} else {
							$modeleStats = $this->getTableObjet('stats_modeles')->insert(array('nom' => $nomModele, 'nomFile' => $file));

							$idModele = (int) $adapter->getDriver()->getLastGeneratedValue();

							$modeleStatsListe = $this->getTableObjet('stats_modeles_liste')->insert(array('idModele' => $idModele, 'idListe' => $idListe, 'tableListes' => $tableListes));
						}

						if ($modeleStats) {
							$success = true;
						}
					} else {
						$msg = 'Erreur lors de la copie du fichier sur le serveur';
					}
				} else {
					$msg = 'Format du fichier invalide (.xlsx ou .xlsm)';
				}
			} else {
				$msg = 'Choisir un fichier à importer';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function infosListeStatsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$msg = '';

			$post = $request->getPost();
			$modeListe = strtolower($post->modeListe);
			$idListe = (int) $post->idListe;

			// Récupérer les modèles liés à la liste
			if ($modeListe == 'dp') {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				$tableListes = 'dp_listes';
			} else {
				$liste = $this->getTableObjet('listes')->select(array('id' => $idListe))->current();
				$tableListes = 'listes';
			}

			if ($liste) {
				// Récupérer tous les modèles
				$modeles = $this->getTableObjet('stats_modeles')->select(array('deleted' => 0))->toArray();

				// Ajouter les modeles qui appartiennent à la liste dans un autre tableau
				$modelesListe = array();
				foreach ($modeles as $key => $modele) {
					$modele['href'] = '/docs/modeles/statsListes/'.$modele['nomFile'];

					// Ajouter les types de suivis liés au modèle
					$modelesSuivis = $this->getTableObjet('stats_modeles_type_suivis')->select(array('idModele' => $modele['id']))->toArray();
					$typesSuivis = array();
					foreach ($modelesSuivis as $key => $modeleSuivis) {
						$typeSuivi = $this->getTableObjet('type_suivi')->select(array('id' => $modeleSuivis['idTypeSuivis']))->current();
						$typesSuivis[] = $typeSuivi;
					}
					$modele['typesSuivis'] = $typesSuivis;

					// MAJ le tab de modeleListe si necessaire
					$modeleListes = $this->getTableObjet('stats_modeles_liste')->select(array('idModele' => $modele['id'], 'idListe' => $idListe, 'tableListes' => $tableListes))->toArray();
					if ($modeleListes) {
						$modelesListe[] = $modele;
					}
				}

				// Récupérer tous les types de suivis autorisé pour l'utilisateur
				$typesSuivis = $this->getTableObjet('type_suivi')->select()->toArray();
				$typesSuivisAuth = array();
				foreach ($typesSuivis as $key => $typeS) {
					if ($_SESSION['USERDROIT']['mode-input-typesuivis-'.$typeS['id']] == 'W' || $_SESSION['USERDROIT']['mode-input-typesuivis-'.$typeS['id']] == 'R') {
						$typesSuivisAuth[] = $typeS;
					}
				}
			} else {
				$msg = 'La liste est introuvable';
			}

			return new JsonModel(array('msg' => $msg, 'allModeles' => $allModeles, 'modelesListe' => $modelesListe, 'modeListe' => $modeListe, 'typesSuivis' => $typesSuivisAuth));
		}
	}

	public function supprModeleStatsAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$success = false;
			$msg = 'Erreur lors de la suppression du modèle';

			$idModele = (int) $request->getPost('idModele');
			$deleted = $this->getTableObjet('stats_modeles')->update(array('deleted' => '1'), array('id' => $idModele));
			if ($deleted) {
				$this->getTableObjet('stats_modeles_liste')->delete(array('idModele' => $idModele));
				$this->getTableObjet('stats_modeles_champs')->delete(array('idModele' => $idModele));
				$this->getTableObjet('stats_modeles_type_suivis')->delete(array('idModele' => $idModele));
				$success = true;
				$msg = 'Modèle supprimé';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function addTypeSuivisModeleAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$success = false;
			$msg = "Erreur lors de l'ajout de ce type de suivi au modèle";

			$idModele = (int) $request->getPost('idModele');
			$idTypeSuivis = (int) $request->getPost('idTypeSuivis');

			$insert = $this->getTableObjet('stats_modeles_type_suivis')->insert(array('idModele' => $idModele, 'idTypeSuivis' => $idTypeSuivis));
			if ($insert) {
				$success = true;
				$msg = '';
			}

			return new JsonModel(array('success' => true, 'msg' => $msg));
		}
	}

	public function supprTypeSuivisModeleAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$idModele = (int) $request->getPost('idModele');
			$idTypeSuivis = (int) $request->getPost('idTypeSuivis');

			$this->getTableObjet('stats_modeles_type_suivis')->delete(array('idModele' => $idModele, 'idTypeSuivis' => $idTypeSuivis));

			return new JsonModel(array('success' => true, 'msg' => 'Opération réussie'));
		}
	}

	public function getChampsModelesStatsAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId = $user->getId();
		}

		if ($request->isPost() && $gestId) {
			$success = false;
			$msg = '';

			$idModele = (int) $request->getPost('idModele');
			$modeleListe = $this->getTableObjet('stats_modeles_liste')->select(array('idModele' => $idModele))->current();

			if ($idModele && $gestId && $modeleListe) {

				// Récupérer la campagne de la liste à partir du modèle
				$campagneModele = '';
				if ($modeleListe->tableListes == 'listes') {
					$campagneModele = '3';
				} elseif ($modeleListe->tableListes == 'dp_listes') {
					$campagneModele = '2';
				}

				$success = true;

				$html = ''; // Html des champs sous forme d'accordéons

				// Récupérer toutes les campagnes actives du gestionnaire
				$campagnesDeGest = [];
				$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
				if ($gestionnaire_campagnes) {
					$html .= '<hr style="margin-bottom: 0">';
					$html .= '<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: center;">';
					$html .= '<h3>Champs du modèle</h3>';
					$html .= '<div>';
					$html .= '<button onclick=validerChampsModele('.$idModele.') type="button" class="btn btn-success" id="validerChampsModele1">Valider le choix des champs</button>';
					$html .= '<button onclick=annulerChoixChamps('.$idModele.') type="button" style="margin-left:10px" class="btn btn-danger" id="annulerChoixChamps1">Annuler</button>';
					$html .= '</div>';
					$html .= '</div>';
					$html .= '<div id="accordionCampagnes" class="panel-group">';

					foreach ($gestionnaire_campagnes as $row) {
						if ($row->idCampagne == 0) {
							continue;
						}
						$campagne = $this->getTableObjet('campagnes')->select(array('id' => $row->idCampagne))->current();
						if ($campagne->archive == '1') {
							continue;
						}
						if ($campagne->type != $campagneModele) {
							continue;
						}

						$idCamp = $campagne->id;
						// Rechercher si la campagne est cochée
						$campModele = $this->getTableObjet('stats_modeles_champs')->select(array('idModele' => $idModele, 'idTable' => $idCamp, 'table' => 'campagnes'))->current();
						$campChecked = '';
						if ($campModele) {
							$campChecked = 'checked';
						}

						$html .= '<div class="panel panel-success">';

						$html .= '<div class="panel-heading">';
						$html .= '<h4 class="panel-title">';
						$html .= '<input onchange=toggleCheckboxCamp(this,'.$idCamp.') class="checkCamp idCamp_'.$idCamp.'" type="checkbox" id="camp_'.$idCamp.'" data-idcamp="'.$idCamp.'" '.$campChecked.'>';
						$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#accordionCampagnes" href="#collapse_camp_'.$idCamp.'">';
						$html .= $campagne->nom;
						$html .= '</a>';
						$html .= '</h4>';
						$html .= '</div>';

						$html .= '<div id="collapse_camp_'.$idCamp.'" class="panel-collapse collapse">';
						$html .= '<div class="panel-body">';

						// Parcourir formulaires
						$formulaires = $this->getTableObjet('formulaires')->select(array('idCampagne' => $idCamp, 'active' => '1'))->toArray();
						foreach ($formulaires as $keyForm => $form) {
							if ($form['nom'] == 'IDENTIFICATION') {
								continue;
							}
							$idForm = $form['id'];

							// Rechercher si le formulaire est coché
							$formModele = $this->getTableObjet('stats_modeles_champs')->select(array('idModele' => $idModele, 'idTable' => $idForm, 'table' => 'formulaires'))->current();
							$formChecked = '';
							if ($formModele) {
								$formChecked = 'checked';
							}

							$html .= '<div class="panel panel-info">';

							$html .= '<div class="panel-heading">';
							$html .= '<h4 class="panel-title">';
							$html .= '<input onchange=toggleCheckboxForm(this,'.$idForm.') class="checkForm idForm_'.$idForm.' idCamp_'.$idCamp.'" type="checkbox" id="form_'.$idForm.'" data-idform="'.$idForm.'" '.$formChecked.'>';
							$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#collapse_camp_'.$idCamp.'" href="#collapse_form_'.$idForm.'">';
							$html .= $form['nom'];
							$html .= '</a>';
							$html .= '</h4>';
							$html .= '</div>';

							$html .= '<div id="collapse_form_'.$idForm.'" class="panel-collapse collapse">';
							$html .= '<div class="panel-body">';

							// Parcourir champs avec order by row, column
							$sqlChampsOrder = "SELECT * FROM champs_formulaires WHERE champs_formulaires.idFormulaire = $idForm AND champs_formulaires.active = '1' AND (champs_formulaires.idType IN ('1','2','3','5','8','9','12','13','18','19') OR champs_formulaires.equivalentSql IN ('nom', 'prenom', 'age')) ORDER BY champs_formulaires.row, champs_formulaires.column";
							$rowsChampsOrder = $adapter->query($sqlChampsOrder)->execute();
							$champs = array();
							foreach ($rowsChampsOrder as $rowCO) {
								$champs[] = $rowCO;
							}
							foreach ($champs as $keyChamp => $champ) {
								$idChamp = $champ['id'];
								$champChecked = '';

								// Rechercher si le formulaire est coché
								$champModele = $this->getTableObjet('stats_modeles_champs')->select(array('idModele' => $idModele, 'idTable' => $idChamp, 'table' => 'champs_formulaires'))->current();
								$champChecked = '';
								if ($champModele) {
									$champChecked = 'checked';
								}

								$html .= '<div class="form-group col-sm-4" style="margin-bottom: 10px;">';
								$html .= '<input class="checkChamp idForm_'.$idForm.' idCamp_'.$idCamp.'" type="checkbox" id="champ_'.$idChamp.'" data-idchamp="'.$idChamp.'" name="champ_'.$idChamp.'" value="'.$champ['name'].'" '.$champChecked.' >';
								$html .= '<label style="margin-left: 5px; font-weight: 400;" for="champ_'.$idChamp.'" style="font-weight: normal">'.$champ['libelle'].'</label>';
								$html .= '</div>';
							}
							$html .= '</div>';
							$html .= '</div>';
							$html .= '</div>';
						}
						$html .= '</div>';
						$html .= '</div>';
						$html .= '</div>';
					}
					$html .= '</div>';

					$html .= '<div style="margin-top: 20px; margin-bottom: 10px; display: flex; justify-content: center;">';
					$html .= '<button onclick=validerChampsModele('.$idModele.') type="button" class="btn btn-success" id="validerChampsModele2">Valider le choix des champs</button>';
					$html .= '<button onclick=annulerChoixChamps('.$idModele.') type="button" style="margin-left:10px" class="btn btn-danger" id="annulerChoixChamps2">Annuler</button>';
					$html .= '</div>';
				} else {
					$msg = "Vous n'avez droit à aucune campagne de ce type de dossiers";
				}
			} else {
				$msg = 'Modèle introuvable';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg, 'htmlChampsAccordeons' => $html));
		} else {
			return new JsonModel(array('success' => false, 'msg' => 'Pb idGestionnaire'));
		}
	}

	public function getChampsExtListeAction()
	{
		$request = $this->getRequest();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId = $user->getId();
		}

		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		if ($request->isPost() && $gestId) {
			$success = false;
			$msg = '';

			$idListe = (int) $request->getPost('idListe');
			$modeListe = $request->getPost('modeListe');
			if ($gestId && $idListe) {

				## Récupérer le type de la campagne de la liste
				## Pour l'instant 3 en dur
				$campagneModele = '3';
				// $campagneModele = '';
				// if ($modeleListe->tableListes == 'listes') {
				// 	$campagneModele = '3';
				// } elseif ($modeleListe->tableListes == 'dp_listes') {
				// 	$campagneModele = '2';
				// }

				## Profil du gestionnaire
				## ~~~~~~~~~~~~~~~~~~~~~~
				$profileGest = $this->getUserTable()->getUserProfil($gestId)->role_id;

				## Html des champs sous forme d'accordéons
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$html = '';

				## Récupérer toutes les campagnes actives du gestionnaire
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$campagnesDeGest = [];

				$gestionnaire_campagnes = $this->getTableObjet('gestionnaire_campagnes')->select(array('idGestionnaire' => $gestId));
				if ($gestionnaire_campagnes) {

					$html .= '<div style="margin-top: 10px; margin-bottom: 20px; display: flex; justify-content: center;">';
					$html .= '<input id="modeListeExt" type="hidden" value="'.$modeListe.'">';
					if ($modeListe == 'listes') {
						$html .= '<button onclick=validerChampsListeExt('.$idListe.') type="button" class="btn btn-success" id="id-export-csv">Valider le choix des champs et lancer l\'extraction</button>';
					} elseif ($modeListe == 'dp_listes') {
						$html .= '<button onclick=validerChampsListeExtDp('.$idListe.') type="button" class="btn btn-success" id="id-export-csv">Valider le choix des champs et lancer l\'extraction</button>';
					} elseif ($modeListe == 'loge_listes') {
						$html .= '<button onclick=validerChampsListeExtLoge('.$idListe.') type="button" class="btn btn-success" id="id-export-csv">Valider le choix des champs et lancer l\'extraction</button>';
					}

					$html .= '<button onclick=annulerChoixListeExt('.$idListe.') type="button" style="margin-left:10px" class="btn btn-danger" id="annulerChampsListeExt1">Annuler</button>';
					$html .= '</div>';
					$html .= '<div id="accordionCampagnesListeExt" class="panel-group">';

					foreach ($gestionnaire_campagnes as $row) {
						if ($row->idCampagne == 0) {
							continue;
						}
						$campagne = $this->getTableObjet('campagnes')->select(array('id' => $row->idCampagne))->current();
						if ($campagne->archive == '1') {
							continue;
						}
						// if ($campagne->type != $campagneModele) {
						// 	continue;
						// }

						## Rechercher si la campagne est cochée
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$idCamp = $campagne->id;
						// $campModele = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe, 'idTable' => $idCamp, 'table' => 'campagnes'))->current();
						$campChecked = '';
						// if ($campModele) {
						// 	$campChecked = 'checked';
						// }

						$html .= '<div class="panel panel-success">';

						$html .= '<div class="panel-heading">';
						$html .= '<h4 class="panel-title">';
						$html .= '<input onchange=toggleCheckboxCampListeExt(this,'.$idCamp.') class="checkCampListeExt idCamp_'.$idCamp.'" type="checkbox" id="camp_'.$idCamp.'" data-idcamp="'.$idCamp.'" '.$campChecked.'>';
						$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#accordionCampagnesListeExt" href="#collapse_camp_listeext_'.$idCamp.'">';
						$html .= $campagne->nom;
						$html .= '</a>';
						$html .= '</h4>';
						$html .= '</div>';

						$html .= '<div id="collapse_camp_listeext_'.$idCamp.'" class="panel-collapse collapse">';
						$html .= '<div class="panel-body">';

						## Parcourir les formulaires de la campagne
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$formulaires = $this->getTableObjet('formulaires')->select(array('idCampagne' => $idCamp, 'active' => '1'))->toArray();
						foreach ($formulaires as $keyForm => $form) {

							if ($form['nom'] == 'IDENTIFICATION') {
								continue;
							}

							$idForm = $form['id'];

							## Vérifier que l'utilisateur à les droits sur le formulaire
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$droitUserForm = $this->getTableObjet('formulaires_profile')->select(array('idFormulaire' => $idForm, 'idProfile' => $profileGest))->current();
							if (!$droitUserForm) {
								continue;
							}

							## Rechercher si le formulaire est coché
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							// $formModele = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe, 'idTable' => $idForm, 'table' => 'formulaires'))->current();
							$formChecked = '';
							// if ($formModele) {
							// 	$formChecked = 'checked';
							// }

							$html .= '<div class="panel panel-info">';

							$html .= '<div class="panel-heading">';
							$html .= '<h4 class="panel-title">';
							$html .= '<input onchange=toggleCheckboxFormListeExt(this,'.$idForm.') class="checkFormListeExt idForm_'.$idForm.' idCamp_'.$idCamp.'" type="checkbox" id="form_'.$idForm.'" data-idform="'.$idForm.'" '.$formChecked.'>';
							$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#collapse_camp_listeext_'.$idCamp.'" href="#collapse_form_listeext_'.$idForm.'">';
							$html .= $form['nom'];
							$html .= '</a>';
							$html .= '</h4>';
							$html .= '</div>';

							$html .= '<div id="collapse_form_listeext_'.$idForm.'" class="panel-collapse collapse">';
							$html .= '<div class="panel-body">';

							## Parcourir les champs avec order by row, column du formualaire
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$sqlChampsOrder = "SELECT * FROM champs_formulaires WHERE champs_formulaires.idFormulaire = $idForm AND champs_formulaires.active = '1' AND champs_formulaires.idType != '10' ORDER BY champs_formulaires.row, champs_formulaires.column";
							$rowsChampsOrder = $adapter->query($sqlChampsOrder)->execute();
							$champs = array();
							foreach ($rowsChampsOrder as $rowCO) {
								$champs[] = $rowCO;
							}
							foreach ($champs as $keyChamp => $champ) {
								$idChamp = $champ['id'];
								$champChecked = '';

								## Rechercher si le champ est coché
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								// $champModele = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe, 'idTable' => $idChamp, 'table' => 'champs_formulaires'))->current();
								$champChecked = '';
								// if ($champModele) {
								// 	$champChecked = 'checked';
								// }

								$html .= '<div class="form-group col-sm-4" style="margin-bottom: 10px;">';
								$html .= '<input class="checkChampListeExt idForm_'.$idForm.' idCamp_'.$idCamp.'" type="checkbox" id="champ_'.$idChamp.'" data-idchamp="'.$idChamp.'" name="champ_listeext'.$idChamp.'" value="'.$champ['name'].'" '.$champChecked.' >';
								$html .= '<label style="margin-left: 5px; font-weight: 400;" for="champ_'.$idChamp.'" style="font-weight: normal">'.$champ['libelle'].'</label>';
								$html .= '</div>';
							}

							$html .= '</div>';
							$html .= '</div>';
							$html .= '</div>';
						}

						$html .= '</div>';
						$html .= '</div>';
						$html .= '</div>';
					}


					## ************** Ajout de champs logement **************
					if($modeListe == 'listes' || $modeListe == 'loge_listes'){
						$idCamp = '-1';
						$html .= '<div class="panel panel-success">';

						$html .= '<div class="panel-heading">';
						$html .= '<h4 class="panel-title">';
						$html .= '<input onchange=toggleCheckboxCamplogeListeExt(this,'.$idCamp.') class="checkCampListeExt idCamploge_'.$idCamp.'" type="checkbox" id="camploge_'.$idCamp.'" data-idcamploge="'.$idCamp.'" '.$campChecked.'>';
						$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#accordionCampagnesListeExt" href="#collapse_camploge_listeext_'.$idCamp.'">';
						$html .= 'Formulaires Logements';
						$html .= '</a>';
						$html .= '</h4>';
						$html .= '</div>';

						$html .= '<div id="collapse_camploge_listeext_'.$idCamp.'" class="panel-collapse collapse">';
						$html .= '<div class="panel-body">';

						## Parcourir les formulaires de la campagne
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$formulaires = $this->getFormulairesLogeTable()->fetchAllActiveByGest($idProfile);
						foreach ($formulaires as $keyForm => $formObj) {
							$form = get_object_vars($formObj);
							$idForm = $form['id'];


							## Rechercher si le formulaire est coché
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							// $formModele = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe, 'idTable' => $idForm, 'table' => 'formulaires'))->current();
							$formChecked = '';
							// if ($formModele) {
							// 	$formChecked = 'checked';
							// }

							$html .= '<div class="panel panel-info">';

							$html .= '<div class="panel-heading">';
							$html .= '<h4 class="panel-title">';
							$html .= '<input onchange=toggleCheckboxFormlogeListeExt(this,'.$idForm.') class="checkFormlogeListeExt idForm_'.$idForm.' idCamploge_'.$idCamp.'" type="checkbox" id="formloge_'.$idForm.'" data-idformloge="'.$idForm.'" '.$formChecked.'>';
							$html .= '<a style="margin-left: 5px;" data-toggle="collapse" data-parent="#collapse_camploge_listeext_'.$idCamp.'" href="#collapse_formloge_listeext_'.$idForm.'">';
							$html .= $form['nom'];
							$html .= '</a>';
							$html .= '</h4>';
							$html .= '</div>';

							$html .= '<div id="collapse_formloge_listeext_'.$idForm.'" class="panel-collapse collapse">';
							$html .= '<div class="panel-body">';

							## Parcourir les champs avec order by row, column du formualaire
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$sqlChampsOrder = "SELECT * FROM champs_formulaires_loge WHERE champs_formulaires_loge.idFormulaire = $idForm AND champs_formulaires_loge.active = '1' AND champs_formulaires_loge.idType != '10' ORDER BY champs_formulaires_loge.row, champs_formulaires_loge.column";
							$rowsChampsOrder = $adapter->query($sqlChampsOrder)->execute();
							$champs = array();
							foreach ($rowsChampsOrder as $rowCO) {
								$champs[] = $rowCO;
							}
							foreach ($champs as $keyChamp => $champ) {
								$idChamp = $champ['id'];
								$champChecked = '';

								## Rechercher si le champ est coché
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								// $champModele = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe, 'idTable' => $idChamp, 'table' => 'champs_formulaires'))->current();
								$champChecked = '';
								// if ($champModele) {
								// 	$champChecked = 'checked';
								// }

								$html .= '<div class="form-group col-sm-4" style="margin-bottom: 10px;">';
								$html .= '<input class="checkChamplogeListeExt idFormloge_'.$idForm.' idCamploge_'.$idCamp.'" type="checkbox" id="champloge_'.$idChamp.'" data-idchamploge="'.$idChamp.'" name="champloge_listeext'.$idChamp.'" value="'.$champ['name'].'" '.$champChecked.' >';
								$html .= '<label style="margin-left: 5px; font-weight: 400;" for="champloge_'.$idChamp.'" style="font-weight: normal">'.$champ['libelle'].'</label>';
								$html .= '</div>';
							}

							$html .= '</div>';
							$html .= '</div>';
							$html .= '</div>';
						}

						$html .= '</div>';
						$html .= '</div>';
						$html .= '</div>';
					}
					//fin ajout champs logement

					$html .= '</div>';

					// $html .= '<div style="margin-top: 20px; margin-bottom: 10px; display: flex; justify-content: center;">';
					// $html .= '<button onclick=validerChampsListeExt('.$idListe.') type="button" class="btn btn-success" id="validerChampsListeExt2">Valider le choix des champs</button>';
					// $html .= '<button onclick=annulerChoixListeExt('.$idListe.') type="button" style="margin-left:10px" class="btn btn-danger" id="annulerChampsListeExt2">Annuler</button>';
					// $html .= '</div>';

					$success = true;
				} else {
					$msg = "Vous n'avez droit à aucune campagne de ce type de dossiers";
				}
			} else {
				$idListe = 'Veuillez choisir une liste avant de lancer une extraction';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg, 'htmlChampsAccordeons' => $html));
		} else {
			return new JsonModel(array('success' => false, 'msg' => 'Une erreur est survenue avec votre identifiant. Veuillez redémarrer une session.'));
		}
	}

	public function saveChampsModeleAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$success = false;
			$msg = '';

			$idModele = (int) $request->getPost('idModele');

			if ($idModele) {
				// Commencer par supprimer les champs du modèle
				$this->getTableObjet('stats_modeles_champs')->delete(array('idModele' => $idModele));

				// Save les campagnes
				$idsCampagne = $request->getPost('idsCampagnes');
				if ($idsCampagne && count($idsCampagne) > 0) {
					foreach ($idsCampagne as $idCamp) {
						$this->getTableObjet('stats_modeles_champs')->insert(array('idModele' => $idModele, 'idTable' => $idCamp, 'table' => 'campagnes'));
					}
				}

				// Save les formulaires
				$idsForm = $request->getPost('idsForm');
				if ($idsForm && count($idsForm) > 0) {
					foreach ($idsForm as $idForm) {
						$this->getTableObjet('stats_modeles_champs')->insert(array('idModele' => $idModele, 'idTable' => $idForm, 'table' => 'formulaires'));
					}
				}

				// Save les champs_formulaires
				$idsChamps = $request->getPost('idsChamps');
				if ($idsChamps && count($idsChamps) > 0) {
					foreach ($idsChamps as $idChamp) {
						// Save aussi le name du champ (besoin plus tard de group by champName)
						$champ = $this->getTableObjet('champs_formulaires')->select(array('id' => $idChamp))->current();
						$this->getTableObjet('stats_modeles_champs')->insert(array('idModele' => $idModele, 'idTable' => $idChamp, 'table' => 'champs_formulaires', 'champName' => $champ->name));
					}
				}

				$success = true;
				$msg = 'Les champs choisis sont bien liés au modèle.';
			} else {
				$msg = 'Modèle introuvable';
			}
			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function saveChampsListeExtAction()
	{

		$request = $this->getRequest();
		if ($request->isPost()) {
			$success = false;
			$msg = '';

			$idListe = (int) $request->getPost('idListe');

			if ($idListe) {

				## Commencer par supprimer les champs à extraire de la liste
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$this->getTableObjet('listes_champs_ext')->delete(array('idListe' => $idListe));

				## Save les campagnes
				## ~~~~~~~~~~~~~~~~~~
				$idsCampagne = $request->getPost('idsCampagnes');
				if ($idsCampagne && count($idsCampagne) > 0) {
					foreach ($idsCampagne as $idCamp) {
						$this->getTableObjet('listes_champs_ext')->insert(array('idListe' => $idListe, 'idTable' => $idCamp, 'table' => 'campagnes'));
					}
				}

				## Save les formulaires
				## ~~~~~~~~~~~~~~~~~~~~
				$idsForm = $request->getPost('idsForm');
				if ($idsForm && count($idsForm) > 0) {
					foreach ($idsForm as $idForm) {
						$this->getTableObjet('listes_champs_ext')->insert(array('idListe' => $idListe, 'idTable' => $idForm, 'table' => 'formulaires'));
					}
				}

				## Save les champs_formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$idsChamps = $request->getPost('idsChamps');
				if ($idsChamps && count($idsChamps) > 0) {
					foreach ($idsChamps as $idChamp) {
						// Save aussi le name du champ (besoin plus tard de group by champName)
						$champ = $this->getTableObjet('champs_formulaires')->select(array('id' => $idChamp))->current();
						$this->getTableObjet('listes_champs_ext')->insert(array('idListe' => $idListe, 'idTable' => $idChamp, 'table' => 'champs_formulaires', 'champName' => $champ->name));
					}
				}

				## Save les formulaires logement : formulaires_loge
				## ~~~~~~~~~~~~~~~~~~~~
				$idsForm = $request->getPost('idsFormloge');
				if ($idsForm && count($idsForm) > 0) {
					foreach ($idsForm as $idForm) {
						$this->getTableObjet('listes_champs_ext')->insert(array('idListe' => $idListe, 'idTable' => $idForm, 'table' => 'formulaires_loge'));
					}
				}

				## Save les champs_formulaires_loge
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$idsChamps = $request->getPost('idsChampsloge');
				if ($idsChamps && count($idsChamps) > 0) {
					foreach ($idsChamps as $idChamp) {
						// Save aussi le name du champ (besoin plus tard de group by champName)
						$champ = $this->getTableObjet('champs_formulaires_loge')->select(array('id' => $idChamp))->current();
						$this->getTableObjet('listes_champs_ext')->insert(array('idListe' => $idListe, 'idTable' => $idChamp, 'table' => 'champs_formulaires_loge', 'champName' => $champ->name));
					}
				}

				$success = true;
				$msg = 'Les champs sont bien enregistrés pour extraction';
			} else {
				$msg = 'Liste introuvable';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function renameModeleStatsAction()
	{
		$request = $this->getRequest();
		if ($request->isPost()) {
			$idModele = (int) $request->getPost('idModele');
			$newNom = $request->getPost('newNom');
			$newNomFile = str_replace(' ', '_', $newNom);

			$success = false;
			$msg = '';

			// renommer le fichier
			$modele = $this->getTableObjet('stats_modeles')->select(array('id' => $idModele))->current();
			$path = getcwd()."/public/docs/modeles/statsListes/";
			$ext = pathinfo($path.$modele->nomFile, PATHINFO_EXTENSION);
			$rename = rename($path.$modele->nomFile, $path.$newNomFile.".".$ext);

			if ($rename) {
				$updated = $this->getTableObjet('stats_modeles')->update(array('nom' => $newNom, 'nomFile' => $newNomFile.".".$ext), array('id' => $idModele));
				if ($updated) {
					$success = true;
					$msg = 'Nom du modèle modifié';
				} else {
					$msg = 'Erreur lors de la maj du modèle';
				}
			} else {
				$msg = 'Erreur lors du changement de nom du fichier sur le serveur';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function deleteAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

			$idListe = (int) $request->getPost('id');
			$from = $request->getPost('from');

			$listes = [];
			if ($idListe > 0) {
				if ($from && $from == 'modedp') {
					$mode = "domiciliation";
					$tableName = "domiciliations_listes";
					$list = $this->getTableObjet('domiciliations_listes')->select(array('id' => (int) $idListe))->current();
					$this->getTableObjet('domiciliations_listes')
					->update(array('deleted' => 1), array('id' => $idListe));

					// récuperation des listes par profile utilisateur connecté
					$allListes = $this->getListesDpByProfile($idProfile);
					foreach ($allListes as $liste) {
						//on affiche les listes public
						$nom = $liste->nom;
						if ($liste->type) {
							$nom .= ' ('.$liste->type.')';
						}

						if ($liste->idEtat == '2') {
							$listes[$liste->id] = $nom;
						} elseif ($liste->idUser == $gestId) {
							$listes[$liste->id] = $nom;
						}
					}

					asort($listes);
				} else {
					$mode = "réservation";
					$tableName = "listes";
					$list = $this->getListesTable()->getListe($idListe);
					$this->getListesTable()->deleteListe($idListe);
				}

				$logs = new Logs();
				$operation = "Suppression de la liste $mode : ".$list->nom.", par : ".$user->getDisplayName();
				$dataLog = array('operation' => $operation,
								'dateOperation' => date('Y-m-d H:i:s'),
								'dataBefore' => array(),
								'dataAfter' => array('deleted' => 1),
								'idGestionnaire' => $gestId,
								'tableName' => $tableName);

				$logs->exchangeArray($dataLog);
				$this->getLogsTable()->saveLogs($logs);
			}

			$view = new JsonModel(array('success' => true, 'listes' => $listes));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function dupliquerListeAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isPost()) {
			$idListe = $request->getPost('idListe');
			$listeTable = $request->getPost('listeTable');
			$nomListeDuplique = $request->getPost('nomListeDuplique');

			$success = false;
			$msg = '';

			if ($listeTable == 'listes') {
				$liste = $this->getTableObjet('listes')->select(array('id' => $idListe))->current();
				$tableListes = $this->getTableObjet('listes');
				$tableListesProfil = $this->getTableObjet('liste_profile');
				$tableListesState = $this->getTableObjet('liste_state');
			} elseif ($listeTable == 'dp_listes') {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				$tableListes = $this->getTableObjet('domiciliations_listes');
				$tableListesProfil = $this->getTableObjet('domiciliations_liste_profile');
				$tableListesState = $this->getTableObjet('domiciliations_state');
			}

			if ($liste) {
				// Insertion listes avec les infos de $liste
				$insertListe = $tableListes->insert(array('nom' => trim($nomListeDuplique), 'idUser' => $gestId, 'idEtat' => $liste->idEtat, 'idType' => $liste->idType, 'indicateur' => $liste->indicateur, 'stats' => $liste->stats));

				$idNewListe = $tableListes->lastInsertValue;

				if ($insertListe) {
					// Si l'insertion de la liste est passé, copier aussi profil et state
					if ($listeTable == 'listes') {
						$profiles = $this->getTableObjet('liste_profile')->select(array('idListe' => $idListe))->toArray();
						$state = $this->getTableObjet('liste_state')->select(array('idListe' => $idListe))->current();
					} elseif ($listeTable == 'dp_listes') {
						$profiles = $this->getTableObjet('domiciliations_liste_profile')->select(array('idListe' => $idListe))->toArray();
						$state = $this->getTableObjet('domiciliations_state')->select(array('idListe' => $idListe))->current();
					}

					foreach ($profiles as $key => $profile) {
						$tableListesProfil->insert(array('idListe' => $idNewListe, 'idProfile' => $profile['idProfile']));
					}

					$insertState = $tableListesState->insert(array('data' => $state->data, 'idListe' => $idNewListe, 'dateFilter' => $state->dateFilter, 'numberFilter' => $state->numberFilter, 'configFilters' => $state->configFilters));

					if ($insertState) {
						$success = true;
					} else {
						$msg = "Duplication de l'état de la liste échouée.";
					}
				} else {
					$msg = 'Duplication de la liste échouée.';
				}
			} else {
				$msg = 'Liste introuvable';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg));
		}
	}

	public function mailAction()
	{
		$form = new MailForm();
		$session = new Container('mailing');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$request = $this->getRequest();
		if ($request->isPost()) {
			//on récupère la liste choisi
			$session->liste = $request->getPost('locataire');
		}
		return array('form' => $form);
	}

	public function savecurrentmailAction()
	{
		$session = new Container('mailing');
		$request = $this->getRequest();

		if ($request->isXmlHttpRequest()) {
			$idModele = $request->getPost('id');
			$modeListe = $request->getPost('modeListe');

			if ($modeListe == 'Reservation') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-reservations'] == 'R') ? true : false;
			} elseif ($modeListe == 'Mail') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-mails'] == 'R') ? true : false;
			} elseif ($modeListe == 'Candidats') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-demandes'] == 'R') ? true : false;
			} elseif ($modeListe == 'Facture') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-facture'] == 'R') ? true : false;
			} elseif ($modeListe == 'Prestation') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-prestation'] == 'R') ? true : false;
			} elseif ($modeListe == 'EDL') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-edl'] == 'R') ? true : false;
			} elseif ($modeListe == 'RDV') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-planning-edl'] == 'R') ? true : false;
			} elseif ($modeListe == 'CAF') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-caf'] == 'R') ? true : false;
			} elseif ($modeListe == 'Formulaire') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-form'] == 'R') ? true : false;
			} elseif ($modeListe == 'Logements') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-logements'] == 'R') ? true : false;
			} elseif ($modeListe == 'Colis') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-colis'] == 'R') ? true : false;
			} elseif ($modeListe == 'presents') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-presents'] == 'R') ? true : false;
			} elseif ($modeListe == 'intercontrat') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-intercontrat'] == 'R') ? true : false;
			} elseif ($modeListe == 'SMS') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-sms'] == 'R') ? true : false;
			} elseif (substr($modeListe, 0, 10) == 'typeSuivis') {
				$idTypeSuivis = str_replace('typeSuivis-', '', $modeListe);
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-typesuivis-'.$idTypeSuivis] == 'R') ? true : false;
			} elseif ($modeListe == 'dp') {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-dp'] == 'R') ? true : false;
			} else {
				$modeListeIsRO = ($_SESSION['USERDROIT']['mode-input-reservations'] == 'R') ? true : false;
			}

			$session->modele = null;
			if ($idModele > 0 && !$modeListeIsRO) {
				$modele = new Modelesmail();
				$post	= $request->getPost();
				$modele->exchangeArray($post);
				if (!empty($post['pjName'])) {
					$modele->pj = $post['pjName'];
				}
				$session->modele = $modele;
				$session->post = $post;
			}

			$view = new JsonModel(array(
						'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}
	## compteur des email envoyé
	public function mailSentCounterAction()
	{
		$tools = new Tools();
		$fileName = 'mailCounter_20240528.txt';
		if (!is_dir(getcwd()."/public/docs/mailcounter")) {
			mkdir(getcwd()."/public/docs/mailcounter");
		}
		$fileNameCounter = getcwd()."/public/docs/mailcounter/".$fileName;
		echo $fileNameCounter;

		$handle = fopen($fileNameCounter, 'w+');//replace existing content
		fwrite($handle, '4');
		fclose($handle);

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$sentPost = $request->getPost('sent', 0);
			/*$session = new Container('mailing');
			if(!$session->total && !$session->sent){
				//$session->total = 2;
				//$session->sent = 1;
				//$session->finish = null;
			}
			$total = $session->total;
			$sent = $session->sent;
			$finish = $session->finish;
			*/
			$sent = $sentPost + 1;
			$msg = "$sent mail envoye sur $total";

			$view = new JsonModel(array(
						'msg' => $msg,
						//'total'=>$total,
						'sent' => $sent,
						//'finish'=>$finish,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function envoyerAction()
	{
		$session = new Container('mailing');

		$form = new MailForm();
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$msg = "";
		$error = "";
		$tools = new Tools();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idModele = $request->getPost('id');
			$listeIdReservations = $request->getPost('liste');
			$isResa = $request->getPost('isResa');
			$isSuivis = $request->getPost('isSuivis'); // permet de récupérer les champs_suivis
			$stockerPJ = $request->getPost('stockerPJ');
			$nePasJoindre = $request->getPost('nePasJoindre');
			$modeListe = $request->getPost('mode');//liste, candidat
			$simulerEnvois = $request->getPost('simulerEnvois');
			$exportMails = $request->getPost('exportMails');
			$exportListe = $request->getPost('exportListe', '');//joindre l export d une liste au mail
			$callType = $request->getPost('callType', '');//si on fait appel depuis la ficher usager-Documents ou autre
			//$simulerEnvois = $_POST['simulerEnvois'];
			//print_r(sizeof($listeIdReservations));exit();
			$listeIdSuivis = $request->getPost('listeSuivis');
			$idTypeSuivis = $request->getPost('idTypeSuivis');

			$nePasEnvoyerResident = $request->getPost('nePasEnvoyerResident');
			$mailUniqueAvecPJGroupe = $request->getPost('mailUniqueAvecPJGroupe');//anvois d'un seule mail avec pj par dossier
			$typeListeFact = $request->getPost('typeListeFact', '');//Mode facture(facturesmois)

			$numFactures = array();

			//on verifie si le idModele est composé : si oui c'est un modele campagne
			$idModeleCampArr = explode('-', $idModele);
			$idCampagneModele = $idModeleParent = 0;
			if (sizeof($idModeleCampArr) > 1) {
				$idModeleParent = $idModeleCampArr[0];
				$idCampagneModele = $idModeleCampArr[1];
				$idModele = $idModeleParent;
			}

			$conf = $this->getConfigurationTable()->getConfig(1);

			## Traitement envois de mail depuis l'onglet Document de la fiche usager
			$liensDocsPJ = array();
			if($callType == 'ficheUsagerDocs') {
				//appel depuis la fiche usager-Documents
				$mailSession = new Container('mailing');
				$mailOptions = $mailSession->mailOptions;
				if(!empty($mailOptions)) {
					$liensDocsPJ = $mailOptions['liensDocsPJ'];
					//$idModele = $mailOptions['idModele'];
					$listeIdReservations = array($mailOptions['idResa']);
				}
				//print_r($mailSession->mailOptions);
			}

			$typeModeleDoc = '';
			## Envois de mail depuis le compte financier
			if($callType == 'ficheUsagerCompte') {
				//appel depuis la fiche usager-Documents
				$mailSession = new Container('mailing');
				$mailOptions = $mailSession->mailOptions;
				if(!empty($mailOptions)) {
					$listeIdReservations = array($mailOptions['idResa']);
					$numFact = $mailOptions['noFacture'];
					$typeModeleDoc = trim($mailOptions['typeMail']);//facture/quittance/recu
					$numFactures[$mailOptions['idResa']] = $numFact;
				}
			}

			$idsUsers = $request->getPost('idsUsers', array());
			$usersEmail = array();
			if (!empty($idsUsers)) {
				$users = $this->getUserTable()->getUsersByIdsIn($idsUsers);
				foreach ($users as $u) {
					$usersEmail[$u->user_id] = $u->email;
				}
			}
			$emailDest = !empty($session->post['emailDest']) ? $session->post['emailDest'] : null;
			if ($emailDest) {
				$emailsDest = explode(',', $emailDest);
				$d = 1;
				foreach ($emailsDest as $dest) {
					if ($dest && !in_array($dest, $usersEmail)) {
						$usersEmail['u_'.$d] = $dest;
						$d++;
					}
				}
			}

			## Envois de mail à tout les users de profil lié au modèle
			$pRows = $this->getTableObjet('modeles_email_profile_envois')->select(array('idModele' => $idModele));
			$usersEmailCopie = array();
			$usersEmailCopieCachee = array();
			foreach($pRows as $pRow) {
				$users = $this->getUserTable()->fetchByProfil($pRow->idProfile);
				foreach ($users as $u) {
					if($pRow->typeEnvois == 'dest') {
						$usersEmail[$u->user_id] = $u->email;
					} elseif($pRow->typeEnvois == 'copie') {
						$usersEmailCopie[$u->user_id] = $u->email;
					} elseif($pRow->typeEnvois == 'copieCachee') {
						$usersEmailCopieCachee[$u->user_id] = $u->email;
					}
				}
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele isResa=$isResa count_listeIdReservations=".count($listeIdReservations));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele isResa=$isResa listeIdReservations=".json_encode($listeIdReservations));



			$listesArr = array();

			if (!empty($listeIdReservations)) {
				foreach ($listeIdReservations as $l) {
					if($typeListeFact == 'facturesmois' || strpos($l, '_') !== false) {
						//en mode facture on a la combinaison idResa_numFacture
						$lArr = explode('_', $l);
						$l = $lArr[0];
						$numFact = !empty($lArr[1]) ? $lArr[1] : '';
						if($numFact) {
							$numFactures[$l] = $numFact;
						}
					}
					$listesArr[$l] = $l;
				}
			}

			$listeIdReservations = $listesArr;

			$isBOEnvoisOnly = false;
			if (empty($listeIdReservations) && !empty($usersEmail)) { // && in_array($exportListe,array('csv','pdf','xls'))
				//dans le cas ou on envois le mail que au users BO
				$listeIdReservations = array(-1);
				$isBOEnvoisOnly = true;
			} elseif (empty($listeIdReservations) && empty($usersEmail)) {
				$msg = "Aucun email destinatire renseigner.";
			}


			//echo sizeof($listeIdReservations);exit();

			$fthCompteur = 0;

			//$sess = new Container("mailingList");
			//$listeIdReservations = empty($request->getPost('liste')) ? $sess->listMailing:$request->getPost('liste');



			//$listeIdReservations = array_unique($listeIdReservations);


			$listeMailing = array();
			$listeEnvois = array();


			$modele = $this->getModelesmailTable()->getModele($idModele);
			if ($modele->idType > 2 || $modeListe == "liste") {
				$isResa = 1;
			}
			if ($modeListe == "facture") {
				$isResa = 1;
			}

			$modeleParLangue = array();
			$isAnimation = false;//modèle type animation
			$isFacture = false;

			if ($modele->idType > 2) {
				$typeModele = $this->getTableObjet('type_email')->select(array('id' => $modele->idType))->current();
				$codeType = $typeModele ? $typeModele->code : '';
				if($codeType != 'configurable' && $codeType != 'animation') {
					//on cherche toute les variante de langue de ce modele
					$langues = $this->getLangues();
					foreach ($langues as $codeLange => $langue) {
						$modeleParLangue[$codeLange] = $this->getModelesmailTable()->getModeleByTypeAndLangue($modele->idType, $codeLange);
					}
				}
				if($codeType == 'animation') {
					$isAnimation = true;
				}
				if($codeType == 'facture' && $modeListe == "facture") {
					$isFacture = true;
				}
			}

			if ($session->modele) {
				$modele = $session->modele;
			}


			//option perdue
			$tableC = new Tables('configuration', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$params = $tableC->getTable()->select()->current();

			$optionPerdue = '3';//+3 jours pardefaut
			if ($params->option_perdue) {
				$optionPerdue = $params->option_perdue;
			}

			//recup des champs logements
			$champsResult = $this->getTableObjet('champs_logements')->select(array('table' => 'logements'));
			$champsLoge = array();
			foreach ($champsResult as $chl) {
				$champsLoge[] = $chl;
			}

			$counter = 0;
			$idDp = null;
			$idResa = null;
			$residence = null;
			$pjToZip = array();//pour envois des pièces jointes groupé, dans un seule mail
			$locsById = array();

			if ($modeListe == "dp") {
				$isResa = 0;
			}

			$tableVD = $this->getTableObjet('valeurs_dynamiques');
			$tableCF = $this->getTableObjet('champs_formulaires');

			$session->total = sizeof($listeIdReservations);


			foreach ($listeIdReservations as $row) {
				$idRow = $row;
				if ($isResa) {
					$idResa = $row;
					$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
					$this->getResaTable()->setAdapter($adapter);


					$idApiPms	= 0;
					$idPMS		= 0;
					$ligne = $this->getResaTable()->getResaWithPms($row);

					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");


					if ($ligne) {

						## Identification du PMS associé
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$idApiPms	= $ligne->idApiPms;
						$idPMS		= $ligne->idPMS;

						$loc = $this->getLocatairesTable()->getLocataire($ligne->idLocataire, false);
						if ($simulerEnvois != 1) {
							$ligne = $this->getResaTable()->getListePourMail($row, $loc->langue)->current();
							//$ligne = $this->getResaTable()->getResa($row);
						}

						if (!$ligne) {
							continue;
						}

						//on recupere les tarifs
						$choixR = $this->getChoixTable()->getResaResidence($row, $ligne->idTypeLogementAttribue);
						if ($choixR) {
							$ligne->residence = $choixR->residence;
						}

						//on cherche les tarifs par defaut de la campagne d abord
						$tarifsDefault = $this->getTableObjet("tarifs")->select(array('idTypeLogement' => $ligne->idTypeLogementAttribue, 'idCampagne' => $ligne->idCampagne, 'default' => '1'))->current();

						if ($tarifsDefault) {
							if ($tarifsDefault->loyer) {
								$ligne->loyerTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->loyer);
							}
							if ($tarifsDefault->montantCaution) {
								$ligne->cautionTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->montantCaution);
							}
							if ($tarifsDefault->fraisGestion) {
								$ligne->fraisDossierTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->fraisGestion);
							}
						} else {
							$ligne->loyerTypeLogementAttribue = '';
							$ligne->cautionTypeLogementAttribue = '';
							$ligne->fraisDossierTypeLogementAttribue = '';
						}

						$tarif = $this->getChoixTable()->getChoixTarifs($row, $ligne->idTypeLogementAttribue);
						if ($tarif) {
							if ($tarif->loyerTypeLogementAttribue) {
								$ligne->loyerTypeLogementAttribue = sprintf("%.2f", $tarif->loyer);
							}
							if ($tarif->cautionTypeLogementAttribue) {
								$ligne->cautionTypeLogementAttribue = sprintf("%.2f", $tarif->montantCaution);
							}
							if ($tarif->fraisDossierTypeLogementAttribue) {
								$ligne->fraisDossierTypeLogementAttribue = sprintf("%.2f", $tarif->fraisGestion);
							}
						}

						##residence
						if ($ligne->idLogement) {
							$resid = $this->getLogementTable()->getResidenceDeLogement($ligne->idLogement);
							if ($resid) {
								$residence = $this->getResidencesTable()->getResidence($resid->idResidence);
								if ($residence) {
									$ligne->residence = $residence->nom;
									$ligne->adresseResidence = $residence->adresse;
									$ligne->codePostalResidence = $residence->codePostal;
									$ligne->villeResidence = $residence->ville;
									$ligne->ribSite = $residence->ribSite;
									$ligne->bicSite = $residence->bicSite;
								}
							}
							$logement = $this->getLogementTable()->getLogement($ligne->idLogement);
							if ($logement) {
								foreach ($champsLoge as $ch) {
									if (property_exists($logement, $ch->equivalentSql)) {
										$champName = $ch->code;
										$champEqSql = $ch->equivalentSql;
										if ($champEqSql == 'idTypeBail') {
											$champEqSql = 'typeBail';
										}
										if ($champEqSql == 'idTypeBien') {
											$champEqSql = 'typeBien';
										}

										$champVal = $logement->$champEqSql;
										if (strpos($champEqSql, 'loyer') !== false) {
											$champVal = sprintf("%.2f", $champVal);
										}

										$ligne->$champName = $champVal;
									}
								}
								if ($logement->loyer > 0) {
									$ligne->loyerTypeLogementAttribue = sprintf("%.2f", $logement->loyer);
								}
							}
						}
					} else {
						//si on fait un test de mail auto
						//$loc = $ligne = $this->getLocatairesTable()->getLocataire($row);
					}
				} else {
					if ($modeListe == "candidat") {
						$loc = $ligne = $this->getLocatairesAccesResaTable()->getLocataire($row);
					} elseif ($modeListe == "dp") {
						$idDp = $row;

						$dp = $this->getDomiciliationsTable()->getDomiciliationById($row);
						// var_dump($dp->idLocataire);die();

						if ($dp) {
							$loc = $ligne = $this->getLocatairesTable()->getLocataire($dp->idLocataire, false);
							$ligne->etat = $dp->etat;
							$ligne->idCampagne = $dp->idCampagne;
							$ligne->createdAt = $dp->createdAt;
							$ligne->dateDernierScan = $dp->dateDernierScan;
							$ligne->dateEntree = $dp->dateEntree;
							$ligne->dateSortie = $dp->dateSortie;
						}
					} else {
						//$loc = $ligne = $this->getLocatairesTable()->getLocataire($row);
					}
				}

				###pour re envoyer le mail
				###on cherche dan historique selon, idModele, idLocataire, et dateEnvoi
				/*$hrows = $this->getTableObjet('historique_mail')->select(array('idLocataire'=>$loc->id,'idModele'=>36));
				foreach($hrows as $hr){
					if(strtotime($hr->dateEnvoi) >strtotime('2017-04-04')){
						$ligne = null;
						$loc = null;
					}
				}*/




				if ((!$ligne || !$loc) && $row > 0) {
					if (!$ligne) {
						$msg .= "Reservation introuvable ID $row<br />";
					}
					continue;
				}

				$locsById[$loc->id] = $loc;

				## recup du modele de la langue du locataire
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($loc && !empty($modeleParLangue) && array_key_exists($loc->langue, $modeleParLangue)) {
					$modele = $modeleParLangue[$loc->langue];
				}


				## Recup du modèle spécifique de la campagne ::
				## EDIT 17-05-2023 on l'envois que si on choisi le modèle campagne dans la liste
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if($idCampagneModele) {
					$modeleCamp = $this->getModelescampagneTable()->getModele($idCampagneModele, $modele->id);
					if ($modeleCamp) {
						$modeleObj = new Modelesmail();
						$modele = $modeleObj->mergeWithCampage($modele, $modeleCamp);
					} else {
						$msg .= "Modèle campagne introuvable de la campagne $idCampagneModele<br />";
						continue;
					}
				}

				//print_r($ligne);exit();
				$listeMailing [] = $loc->email;


				$fields = $this->getfields($modele->corps);
				$langue = $loc->langue == "UK" ? "en_US" : "fr_FR";
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa fields=".json_encode($fields));

				## choix de type logement
				$nbrChoix = $this->getChoixTable()->getChoixDeReservation($row);

				$idResidencePremierChoix = null;
				if ($nbrChoix->count() > 0) {
					for ($s = 1;$s <= $nbrChoix->count();$s++) {
						$c = $this->getChoixTable()->getChoixByResaNumero($row, $s);
						if ($c) {
							$vr = "typeLogement".$s;
							$ligne->$vr = $langue == "en_US" ? $c->typeLogementEn : $c->typeLogement;
							$ligne->$vr = utf8_decode($ligne->$vr);
							if ($c->idResidence) {
								$resid = $this->getResidencesTable()->getResidence($c->idResidence);
								if ($resid) {
									$vr = "residence".$s;
									$ligne->$vr = $resid->nom;
								}
							}

							if ($s == 1) {
								if ($c->idResidence) {
									$idResidencePremierChoix = $c->idResidence;
								} else {
									$rc = $this->getChoixTable()->getResaResidence($c->idReservation, $c->idTypeLogement);
									if ($rc) {
										$idResidencePremierChoix = $rc->idResidence;
									}
								}
							}
						}
					}
				}
				## fin choix de type de logement

				## Lecture des champs de documents associés à la résa
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$champsDocEquivalentSql = array();
				$champsDernierMS = array();
				$resa		= $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
				$formulaires	= $this->getTableObjet('formulaires') ->select(array('idCampagne' => $resa->idCampagne))->toArray();

				foreach ($formulaires as $key => $form) {
					$champs_formulaires = $this->getTableObjet('champs_formulaires')
					->select(array(
						'idFormulaire' => $form['id'],
						'idType' => 4,
					))
					->toArray();

					// récupération des champs de type doc
					if (count($champs_formulaires) > 0) {
						foreach ($champs_formulaires as $key => $chf) {
							$champsDocEquivalentSql[$chf['equivalentSql']] = $chf;
						}
					}
					//champs dernier MS
					$tableCF = $this->getTable('champs_formulaires');
					$select = $tableCF->getSql()->select();
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
					$select->join('champs_suivis', 'champs_suivis.id = champs_formulaires.idChampSuivis', array('idCS' => 'id', 'idTypeSuivis'), 'LEFT');
					$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.active' => 1, 'formulaires.active' => 1 ));
					$select->where('(champs_formulaires.equivalentSql IS NOT NULL AND champs_formulaires.equivalentSql != "" AND champs_formulaires.idChampSuivis > 0)');
					$champsMS = $tableCF->selectWith($select);
					foreach($champsMS as $chf){
						$champsDernierMS[$chf->equivalentSql] = array(	'dyn' => 1,
													'typeField' => '',
													'idTypeHtml' => $chf->idType,
													'table' => 'champs_suivis',
													'idChamp' => $chf->idChampSuivis,
													'equivalentSql' => $chf->equivalentSql,
													'sourceListe' => $chf->sourceListe,
													'idTypeSuivis' => $chf->idTypeSuivis,
													'champ' => $chf,
													);
					}

				}

				$attachFiles = array();
				$pjToSavePath = array();
				$exportToDelete = array();

				$vals = array();
				$body = $modele->corps;
				$bodyHisto = $body;
				$locArray = array();
				foreach ($fields as $row) {
					$valeur = $ligne->$row;
					if (substr($row, 0, 6) != "libre_") {
						## Pas la peine de tracer ici car ce n'est pas encore rempli pour les champs dynamiques
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
					}
					/*if($row == "civiliteBDD"){
						$civ = $ligne->civilite;
						$civEn = $ligne->civiliteEn;
						if($valeur == 2){
						$valeur = isset($loc->langue) && $loc->langue=="UK" ? $civEn:$civ;
						}else{
						$valeur = isset($loc->langue) && $loc->langue=="UK" ? $civEn:$civ;
						}
						}*/
					if ($row == "civilite") {
						if (is_numeric($valeur)) {
							$tbl = new Tables('civilites', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
							$civRes = $tbl->getTable()->select(array('id' => $valeur))->current();
							if ($civRes) {
								$trad = $this->getSelectValTraduction(array('idLigne' => $valeur, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
								$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civRes->nomEn : $civRes->nom;
								if ($trad) {
									$valeur = $trad;
								}
							}
						} else {
							$civ = $ligne->civilite;
							$civEn = $ligne->civiliteEn;

							$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civEn : $civ;
							if (is_numeric($loc->civilite)) {
								$trad = $this->getSelectValTraduction(array('idLigne' => $loc->civilite, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
								if ($trad) {
									$valeur = $trad;
								}
							}
						}
					}
					if ($row == "paysLocataire") {
						$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idPays, 'codeLangue' => $langue, 'tableReference' => 'pays'));
						if ($trad) {
							$valeur = $trad;
						}
					}
					if ($row == "nationaliteLocataire") {
						$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idNationalite, 'codeLangue' => $langue, 'tableReference' => 'pays'));
						if ($trad) {
							$valeur = $trad;
						}
					}

					//date option et date du jour
					if ($row == "dateNow") {
						$valeur = date('Y-m-d');
					}
					if ($row == "dateOptionPerdue") {
						$dateOption = $ligne->dateOption;
						if (date('Y', strtotime($dateOption)) < 2000) {
							$dateOption = date('Y-m-d');
						}
						$valeur = date('Y-m-d', strtotime($dateOption." + $optionPerdue day"));
					}


					##### added le 22-06-2017
					if ($row == "typeLogementAttribue" && $loc->langue == "UK" && $ligne->typeLogementAttribueEn != "") {
						$valeur = $ligne->typeLogementAttribueEn;
					}

					if ($row == "delaiPaiement") {
						$valeur = $params->delaiPaiement;
					}

					if ($row == "totalFrais" || $row == "cautionTypeLogementAttribue" || $row == "fraisDossierTypeLogementAttribue") {
						//on cherche les lignes de compte à payer
						$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa));
						$montant = 0;
						$montantCaution = 0;
						$montantFDD = 0;
						foreach ($comptes as $c) {
							if ($c->solde > 0) {
								$montant += $c->solde;
							}
							//on recup les fdd et caution de la table comptes
							if ($c->type == 4 && $c->debit > 0) {
								$montantCaution = sprintf("%.2f", $c->debit);
							}
							if ($c->type == 3 && $c->debit > 0) {
								$montantFDD = sprintf("%.2f", $c->debit);
							}
						}
						if ($row == "cautionTypeLogementAttribue") {
							$valeur = sprintf("%.2f", $montantCaution);
						}
						if ($row == "fraisDossierTypeLogementAttribue") {
							$valeur = sprintf("%.2f", $montantFDD);
						}
						if ($row == "totalFrais") {
							$valeur = sprintf("%.2f", $montant);
						}
					}

					if ($row == "dateProchainPrelevement") {
						$valeur = $this->getResaTable()->getProchaineDatePrelevement($idResa);
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa dateProchainPrelevement=$valeur");
					}
					if ($row == "urlPaiementEmail") {
						## Constitution de l'url d'appel
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						try {
							$sm = $this->getServiceLocator();
							$return	= $sm->get('Application\Model\UrlTokenTable')->buildUrlToken($idResa);
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa ERROR-exception=".$ex->getMessage());
						}
						if ($return && is_array($return)) {
							$idToken	= $return['idToken'];
							$tokenCrypt	= $return['tokenCrypt'];

							$valeur	= sprintf("<a href='https://%s/payment/demPaiement/T%s'>ici</a>", $_SERVER[SERVER_NAME], $tokenCrypt);
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa urlPaiementEmail=$valeur");
						}
					}


					if (substr($row, 0, 3) == "CF_") {
						## Se connecter au PMS associé à cette demande
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$valeur	= "??";
						if ($idApiPms && $idPMS) {
							$this->initPMS($idApiPms, $idResa);

							## Traitement en fonction du PMS
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if ($this->pms) {
								if ($this->pms->getClassName() === "Bredea") {
									## Rien à faire pour l'instant
								} elseif ($this->pms->getClassName() === "CeriFoyer") {
									## Lecture de la variable dans le PMS
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$valeur	= $this->pms->getVariableInMail($row, $idResa, $idPMS);
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
								}
							}
						}
					}

					//on cherche dans la pile pour le modele refus
					if ($isResa && $idResa) {
						$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $idResa))->current();
						if ($pile) {
							if ($row == 'msgErreur') {
								$valeur = $pile->msgErreur;
							}
							if ($row == 'datePaiementFrais' && $pile->dateRefus) {
								$delaiPaiement = $params->delaiPaiement;
								$valeur = date('Y-m-d', strtotime($pile->dateRefus." + $delaiPaiement day"));
							}
						}
					}

					#########

					//pour changer le format de date
					if (substr($row, 0, 4) == "date") {
						if ($loc->langue == "FR" || !$loc->langue) {
							if ($valeur == "0000-00-00") {
								$valeur	= "";
							} elseif ($valeur) {
								$valeur = date('d-m-Y', strtotime($valeur));
							}
						}
					}

					//partie champs dynamique
					$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
					if ($this->getChampsTable()->isDynamique($row)) {
						if (!$locArray) {
							$locArray = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($loc->id, $adapter, $idResa, $idDp, true);
							if(!empty($champsDernierMS)){
								///////////
								## on récup les valeurs des champs suivis
								$rowsData = array();
								if ($idResa) {
									$where = array();
									array_push($where, "reservations.id = $idResa");
									$rowsData = $this->getResaTable()->getListeWithAllFields($adapter, 0, $champsDernierMS, $where, array('config' => $conf, 'callFrom' => 'ficheUsager'));
								} elseif ($idDp) {
									$where = array();
									array_push($where, "domiciliations.id = $idDp");
									$rowsData = $this->getDomiciliationsTable()->getAllDpFields($adapter, 0, $champsDernierMS, $where, array('config' => $conf, 'fetchMode' => 'oneRow', 'idDp' => $idDp, 'callFrom' => 'ficheUsager'));
								}
								if (!empty($rowsData) && !empty($rowsData[0])) {
									$dataSuivis = $rowsData[0];
									if (array_key_exists('idCampagne', $dataSuivis)) {
										unset($dataSuivis['idCampagne']);
									}
									if (array_key_exists('idEtatResa', $dataSuivis)) {
										unset($dataSuivis['idEtatResa']);
									}
									if (array_key_exists('idResidenceOrientation', $dataSuivis)) {
										unset($dataSuivis['idResidenceOrientation']);
									}
									if (array_key_exists('idResidence', $dataSuivis)) {
										unset($dataSuivis['idResidence']);
									}
									$locArray = $this->mergeData($locArray, $dataSuivis);
								}
								////////////
							}
						}
						if ($row != "libre_residence_cao") {
							$valeur = !empty($locArray[$row]) ? $locArray[$row] : "";
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
						}
					}

					## champs catalogue pour le modèle type animation
					if($isAnimation) {
						$modeleAnim = $this->getTableObjet('modeles_email_animation')->select(array('idModele' => $idModele))->current();
						if($modeleAnim && $modeleAnim->idTypeSuivis && $modeleAnim->idCatalogue) {
							if(substr($row, 0, 16) == "libre_catalogue_") {
								$catalogueVals = $this->getCatalogueTable()->getCatalogueAllInfos($modeleAnim->idCatalogue, $adapter, array('modeleDoc' => true, 'langue' => $loc->langue));
								$valeur = !empty($catalogueVals[$row]) ? $catalogueVals[$row] : "";
							} elseif($row == "lienInscriptionAnimation") {
								$config = $this->getConfigurationTable()->getConfig(1);
								$idTypeSuivis = $modeleAnim->idTypeSuivis;
								$idCatalogue = $modeleAnim->idCatalogue;
								$cryptKey = $config->cryptKey;
								$lienStr = "idTypeSuivis=$idTypeSuivis&";
								$lienStr .= "idResa=$idResa&";
								$lienStr .= "idCatalogue=$idCatalogue";
								$lienCrypte = bin2hex($tools->encrypt($lienStr, $cryptKey));
								$baseUrl = $this->getBaseUrl();
								if(substr($baseUrl, -1) == '/') {
									$lienInsc = $baseUrl."reservation/animation?q=$lienCrypte";
								} else {
									$lienInsc = $baseUrl."/reservation/animation?q=$lienCrypte";
								}
								$valeur = '<a href="'.$lienInsc.'" target="_blank">Inscription</a>';
							}
						}
					}

					if (substr($row, 0, 19) == "libre_residence_cao") {
						if (!$locArray) {
							$locArray = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($loc->id, $adapter, $idResa, $idDp, true);
						}
						$idResidenceCao	= $locArray['libre_residence_cao'];
						if ($idResidenceCao) {
							if (!$residenceCao || $residenceCao->id != $idResidenceCao) {
								$residenceCao = $this->getResidencesTable()->getResidence($idResidenceCao);
							}
							if ($residenceCao) {
								if ($row == "libre_residence_cao") {
									$valeur = $residenceCao->nom;
								} elseif ($row == "libre_residence_cao_adresse") {
									$valeur = $residenceCao->adresse;
								} elseif ($row == "libre_residence_cao_codePostal") {
									$valeur = $residenceCao->codePostal;
								} elseif ($row == "libre_residence_cao_ville") {
									$valeur = $residenceCao->ville;
								} elseif ($row == "libre_residence_cao_iban") {
									$valeur = $residenceCao->ribSite;
								} elseif ($row == "libre_residence_cao_bic") {
									$valeur = $residenceCao->bicSite;
								}
							}
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
					}

					//ne pas afficher la photo si le statut est accepté
					if ($row == 'photo' && $loc->photo) {
						$valeur = "";
						if ($loc->statutPhoto == 2) {
							$valeur = "";
						} else {
							$valeur = $this->getGlobalHelper()->getChampTranslation('photo', $ligne->idCampagne, $loc->langue == 'UK' ? 'en_US' : 'fr_FR');
						}
					}
					if ($row == "certificatAssur" && $valeur) {
						if ($ligne->statutAssur == 2) {
							$valeur = "";
						} else {
							$valeur = $this->getGlobalHelper()->getChampTranslation('certificatAssur', $ligne->idCampagne, $loc->langue == 'UK' ? 'en_US' : 'fr_FR');
						}
					}

					## solde cache
					if($row == "pmsSoldeSansCaution" || $row == "pmsSoldeAvecCaution"){
						$soldeCache = $this->getTableObjet('pmsCache')->select(array('idReservation' => $idResa, 'typeCache' => 'solde'))->current();
						if($soldeCache){
							if($row == "pmsSoldeSansCaution"){
								$valeur = sprintf('%.2f', $soldeCache->valeur);
							}else{
								$valeur = sprintf('%.2f', $soldeCache->valeur2);
							}
						}
					}

					## Traitement des statuts de documents
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if (substr($row, -12) == '__statut_doc') {
						$champName	= substr($row, 0, -12);
						$champDoc	= $champsDocEquivalentSql[$champName];
						$idChamp	= $champDoc['id'];
						$vds		= $this->getTableObjet('valeurs_dynamiques') ->select(array('idChamp' => $idChamp, 'idReservation' => $idResa))->toArray();

						$valeur	= 'Absent';
						if (is_array($vds)) {
							$vd	= reset($vds);
							if ($vd) {
								if ($vd['statutDoc']) {
									$statutsDoc	= array(1 => 'Refusé', 2 => 'Validé');
									$valeur		= $statutsDoc[$vd['statutDoc']];
								}
								if (!$valeur) {
									$valeur	= '??';
								}
							}
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] field=$row idChamp=$idChamp valeur=$valeur");
					}

					## Traitement des fins de validité de documents
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if (substr($row, -18) == '__fin_validite_doc') {
						$champName	= substr($row, 0, -18);
						$champDoc	= $champsDocEquivalentSql[$champName];
						$idChamp	= $champDoc['id'];
						$vds		= $this->getTableObjet('valeurs_dynamiques') ->select(array('idChamp' => $idChamp, 'idReservation' => $idResa))->toArray();

						$valeur	= null;
						if (is_array($vds)) {
							$vd	= reset($vds);
							if ($vd) {
								if ($vd['finValidité']) {
									$valeur	= $vd['finValidite'];
								}
							}
						}
					}

					if (strpos($row, "_nom") === false
						&& strpos($row, "pj_manquante") === false
						&& strpos($row, "pj_refuse") === false
						&& strpos($row, "idDemande") === false
						&& strpos($row, "urlDemande") === false
						&& strpos($row, "dateCreationDemande") === false
						&& strpos($row, "demande_raison_impossibilite") === false
						&& strpos($row, "_demande_etatTravaux") === false
					) {
						if (strpos($row, "urlPaiementEmail") === false && strpos($row, "lienInscriptionAnimation") === false) {
							$valeur = nl2br($valeur);
							$valeur = htmlentities($valeur);//echapper les html entities
						}
						$body = str_replace("%".$row."%", $valeur, $body);

						if ($row == "password") {
							$valeur = '**********';
						}
						$bodyHisto = str_replace("%".$row."%", $valeur, $bodyHisto);
					}

					$mChampName = $row;
					if (strpos($row, "_nom") !== false) {
						$mChampName = substr($row, 0, -7);
					}

					// envoie des champs type doc en PJ
					$champS = $this->getTableObjet('champs_suivis')->select(array('name' => $mChampName))->current();


					$idSuivis = "";
					$idResaS = "";
					if (count($listeIdSuivis) > 0) {
						foreach ($listeIdSuivis as $key => $value) {
							if ($idRow == $value['idResa']) {
								$idSuivis = $value['idSuivis'];
								$idResaS = $value['idResa'];
							}
						}
					}

					if (($isSuivis || $idTypeSuivis != "") && $champS && $champS->idType == 4) {
						// on vérifie le champ dans la table champs_suivis
						if ($modeListe == 'dp' && $dp) {
							$allSuivisVal = $this->getTableObjet('suivis_values')
								->select(array('idDp' => $dp->id, 'idSuivis' => $idSuivis, 'idChamp' => $champS->id))->toArray();
						} else {
							// suivis
							// suivis
							$allSuivisVal = $this->getTableObjet('suivis_values')
								->select(array('idResa' => $idResaS, 'idSuivis' => $idSuivis, 'idChamp' => $champS->id))->toArray();
						}

						if (count($allSuivisVal) > 0) {
							foreach ($allSuivisVal as $key => $allS) {
								if ($allS['valeur'] != "") {
									// on check et on récupère le document
									$filePath = getcwd().'/public/docs/locataires/'.$loc->idLocataire.'/suivis/'.$allS['valeur'];

									if (file_exists($filePath)) {
										// ajouter le fichier dans la liste des pièces jointes

										$pjToSavePath[] = $filePath;
										$pjToZip[$loc->id][] = $filePath;

										$ext = pathinfo($filePath, PATHINFO_EXTENSION);
										$mimeTypeImage = ["gif", "jpeg", "jpg", "bmp", "png", "tiff", "webp"];
										$mimeTypeApp = ["pdf", "xls", "json", "xml", "zip"];
										if (in_array($ext, $mimeTypeImage)) {
											$mimeType = "image";
										} elseif (in_array($ext, $mimeTypeApp)) {
											$mimeType = "application";
										}



										$fileContent = fopen($filePath, 'r');
										$attachment = new \Zend\Mime\Part($fileContent);
										$attachment->type = $mimeType."/".$ext;
										$attachment->filename = $allS['valeur'];
										$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
										// Setting the encoding is recommended for binary data
										$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
										$attachFiles[] = $attachment;

										if (strpos($row, "_nom") !== false) {
											$body = str_replace("%".$row."%", $allS['valeur'], $body);
										}
									}
								}
							}
						}
					} else {
						$champsDoc = [];
						$champsDocsEquivalentSql = array();

						$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();

						$formulaires = $this->getTableObjet('formulaires')
						->select(array('idCampagne' => $resa->idCampagne))->toArray();

						foreach ($formulaires as $key => $form) {
							$champs_formulaires = $this->getTableObjet('champs_formulaires')
							->select(array(
								'idFormulaire' => $form['id'],
								'idType' => 4,
								// 'obligatoireDemande' => 1
							))
							->toArray();

							// récupération des champs de type doc
							if (count($champs_formulaires) > 0) {
								foreach ($champs_formulaires as $key => $chf) {
									$champsDoc[] = $chf;
									$champsDocsEquivalentSql[$chf['equivalentSql']] = $chf;
								}
							}
						}
						##syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=$row champsDocsEquivalentSql=".json_encode($champsDocsEquivalentSql) );

						if (array_key_exists($row, array_keys($champsDocsEquivalentSql))) {
							$select = $tableCF->getSql()->select();
							$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFRM' => 'id'));
							$select->where(array('formulaires.idCampagne' => $resa->idCampagne, 'champs_formulaires.equivalentSql' => $row));
							$champDoc = $tableCF->selectWith($select)->current();
							$vdResult = null;
							if ($champDoc) {
								if ($idDp) {
									$vdResult = $tableVD->select(array('idChamp' => $champDoc->id, 'idDp' => $idDp))->current();
								} elseif ($idResa) {
									$vdResult = $tableVD->select(array('idChamp' => $champDoc->id, 'idReservation' => $idResa))->current();
								}
							}



							if ($vdResult && $vdResult->valeur) {
								$docName = $vdResult->valeur;
								// on check et on récupère le document
								$filePath = getcwd().'/public/docs/locataires/'.$loc->idLocataire.'/'.$docName;

								if (file_exists($filePath)) {
									// ajouter le fichier dans la liste des pièces jointes

									$pjToSavePath[] = $filePath;
									$pjToZip[$loc->id][] = $filePath;

									$ext = pathinfo($filePath, PATHINFO_EXTENSION);
									$mimeTypeImage = ["gif", "jpeg", "jpg", "bmp", "png", "tiff", "webp"];
									$mimeTypeApp = ["pdf", "xls", "json", "xml", "zip"];
									if (in_array($ext, $mimeTypeImage)) {
										$mimeType = "image";
									} elseif (in_array($ext, $mimeTypeApp)) {
										$mimeType = "application";
									}

									$fileContent = fopen($filePath, 'r');
									$attachment = new \Zend\Mime\Part($fileContent);
									$attachment->type = $mimeType."/".$ext;
									$attachment->filename = $docName;
									$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
									// Setting the encoding is recommended for binary data
									$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
									$attachFiles[] = $attachment;
								}
							}//
						}

						// $champs = $this->getTableObjet('champs_formulaires')->select(array(''))->toArray();
						if (strpos($row, "pj_refuse") !== false) {
							// $champsDocVide = [];
							$champsDocTxt = "<ul>";
							foreach ($champsDoc as $key => $chd) {
								// on check si la vue est null
								$valeurs_dynamiques = $this->getTableObjet('valeurs_dynamiques')
								->select(array('idChamp' => $chd['id'], 'idReservation' => $idResa, 'statutDoc' => 1))
								->current();
								// le champ n'existe pas ou le champ existe mais on a pas de valeur
								if ($valeurs_dynamiques) {
									// $champsDocVide[] = $chd;
									$champsDocTxt .= '<li>'.$chd['libelle']. "</li>";
								}
							}

							if ($champsDocTxt != "") {
								$champsDocTxt .= "</ul>";
								$body = str_replace("%pj_refuse%", $champsDocTxt, $body);
							}
						} elseif (strpos($row, "pj_manquante") !== false) {
							// $champsDocVide = [];
							$champsDocTxt = "<ul>";
							foreach ($champsDoc as $key => $chd) {
								// si le champ est obligatoire pour le séjour
								// + on a une condition afficher/cacher avec condition ok
								$afficherChamp = true;
								$actions_js = $this->getTableObjet('actions_js')
								->select(array('idChampAttache' => $chd['id'], 'idType' => '1', 'valeur' => '1'))
								->toArray();
								if (count($actions_js) > 0) {
									foreach ($actions_js as $key => $ajs) {
										$vd = $this->getTableObjet('valeurs_dynamiques')
										->select(array('idChamp' => $ajs['idChamp']))
										->current();

										$ac = $this->getTableObjet('actions_conditions')
										->select(array('idAction' => $ajs['id']))->current();

										// si la condition n'est pas rempli
										if ($vd && $ac && strpos($ac->valeurExact, $vd->valeur) === false) {
											if ($ac['operateur'] != 3) {
												$afficherChamp = false;
												break;
											} elseif ($ac && $ac['operateur'] == 3) {
												$champDebut = $this->getChampsFormTable()
												->select(array('id' => $ac->champDebut))->current();
												$champFin = $this->getChampsFormTable()
												->select(array('id' => $ac->champFin))->current();

												$cond = ($champDebut && $champFin)
													|| ($champDebut && $ac->champFin == '-1')
													|| ($champFin && $ac->champDebut == '-1');

												if ($cond) {
													if ($ac->champDebut == '-1') {
														$valeurLocataireDebut = date('Y-m-d');
													} else {
														$valeurLocataireDebut =
														$this->getTableObjet('valeurs_dynamiques')
														->select(array('idChamp' => $ac->champDebut))
														->current();
														$valeurLocataireDebut = $valeurLocataireDebut->valeur;
													}

													if ($ac->champFin == '-1') {
														$valeurLocataireFin = date('Y-m-d');
													} else {
														$valeurLocataireFin =
														$this->getTableObjet('valeurs_dynamiques')
														->select(array('idChamp' => $ac->champFin))
														->current();
														$valeurLocataireFin = $valeurLocataireFin->valeur;
													}

													$dateDebut = new \DateTime($valeurLocataireDebut);
													$dateFin = new \DateTime($valeurLocataireFin);
													$difference = $dateDebut->diff($dateFin);

													if ($ac->unite == "day") {
														$intervalCalculer = $difference->format('%a');
													} elseif ($ac->unite == "week") {
														$intervalCalculer = floor($difference->days / 7);
													} elseif ($ac->unite == "year") {
														$intervalCalculer = $difference->format('%y');
													} else {
														//mois
														$intervalCalculer = $difference->format('%m');
													}

													$valeurDb = $ac->valeurExact;

													if ($ac->operateur == 1) {
														$condition = $intervalCalculer == $valeurDb;
													} elseif ($ac->operateur == 2) {
														$condition = $intervalCalculer <= $valeurDb;
													} elseif ($ac->operateur == 3) {
														$condition = $intervalCalculer >= $valeurDb;
													} elseif ($ac->operateur == 4) {
														$valeurMin = $ac->valeurMin;
														$valeurMax = $ac->valeurMax;

														$condition = $condition && ($valeurMin <= $intervalCalculer) && ($intervalCalculer <= $valeurMax);
													} elseif ($ac->operateur == 5) {
														$condition = $intervalCalculer != $valeurDb;
													}

													$afficherChamp = $condition === true;
													break;
													/*echo "\n critere ".$c->id;
													var_dump($condition);*/
												} else {
													$afficherChamp = true;
													break;
												}
											}
										}
									}
								}

								// var_dump($afficherChamp);die();
								if ($afficherChamp && $chd['obligatoireSejour'] == "1") {
									// on check si la valeur est null
									$valeurs_dynamiques = $this->getTableObjet('valeurs_dynamiques')
									->select(array('idChamp' => $chd['id'], 'idReservation' => $idResa))->current();
									// le champ n'existe pas ou le champ existe mais on a pas de valeur

									if (!$valeurs_dynamiques || ($valeurs_dynamiques && empty($valeurs_dynamiques->valeur))) {
										// $champsDocVide[] = $chd;
										$champsDocTxt .= '<li>'.$chd['libelle']. "</li>";
									}
								}
							}

							if ($champsDocTxt != "") {
								$champsDocTxt .= "</ul>";
								$body = str_replace("%pj_manquante%", $champsDocTxt, $body);
							}
						}
						// else if (strpos($row, "demande_raison_impossibilite") !== false) {
						// }
					}
				}

				//echo $body;exit();

				$subject = $modele->objet;
				$from  = $modele->emailFrom;
				$fromName  = $modele->nomFrom;
				$to = "";
				if ($loc) {
					$to = $loc->emailHec ? $loc->emailHec : $loc->email;
				}
				$toc = $modele->emailCopie;
				if($toc && !is_array($toc)) {
					$toc = explode(',', $toc);
					$toc = array_filter($toc);
				}
				if(!empty($usersEmailCopie)) {
					if(!$toc && !is_array($toc)) {
						$toc = array();
					}
					$toc = array_merge($toc, $usersEmailCopie);
				}
				//$tocc = $modele->emailCopieCachee;
				$to = trim($to);

				if ($nePasEnvoyerResident || $mailUniqueAvecPJGroupe) {
					$to = null;
				}

				//echo "to : $to<br>";continue;


				$tocc = explode(',', $modele->emailCopieCachee);

				if (!$to && !$isBOEnvoisOnly && empty($usersEmail)) {
					if (!$loc) {
						$msg .= "Locataire introuvable pour la reservation ID $row<br />";
					} else {
						$msg .= "Aucun email destinataire pour ".$loc->nom." ".$loc->prenom."<br />";
					}
					continue;
				}

				$toEmail1 = $loc->emailHec ? $loc->email : "";
				$toEmail1 = trim($toEmail1);

				if ($to) {
					$listeEnvois[] = $to;
				}

				//bcc config
				$tableObj = new Tables('type_email', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
				$config = $tableObj->getTable()->select(array('id' => $modele->idType))->current();

				$sysBcc = array();
				if ($config->bcc) {
					$sysBcc = explode(',', $config->bcc);
				}


				$bcc = array_merge($tocc, $sysBcc);
				if(!empty($usersEmailCopieCachee)) {
					$bcc = array_merge($bcc, $usersEmailCopieCachee);
				}
				$bcc = array_filter($bcc);

				$idResidence = $resid ? $resid->idResidence : 0;
				if (!$idResidence && $idResidencePremierChoix) {
					$idResidence = $idResidencePremierChoix;
				}


				//on prend l'adresse mail du responsable residence si on a une valeur egale à 'responsableresidence@wheb.fr'
				if($idResidence) {
					$residenceRes = $this->getResidencesTable()->getResidence($idResidence);
					if($residenceRes && $residenceRes->email) {
						//copie
						if(is_array($toc) && !empty($toc)) {
							foreach($toc as $index => $adrEmail) {
								if($adrEmail == 'responsableresidence@wheb.fr') {
									$toc[$index] = $residenceRes->email;
								}
							}
						}
						//copie cachée
						if(is_array($bcc) && !empty($bcc)) {
							foreach($bcc as $index => $adrEmail) {
								if($adrEmail == 'responsableresidence@wheb.fr') {
									$bcc[$index] = $residenceRes->email;
								}
							}
						}
						//email dest
						if($emailDest && !empty($usersEmail)) {
							foreach($usersEmail as $index => $adrEmail) {
								if($adrEmail == 'responsableresidence@wheb.fr') {
									$usersEmail[$index] = $residenceRes->email;
								}
							}
						}
					}
				}


				$mailService = $this->getServiceLocator()->get('MtMail\Service\Mail');

				$headers = array();
				if ($params->envoyerUneCopieMail == 1 && $counter > 0) { // AAK : supprimer le mode où on ne devait envoyer à cc et bcc que seule fois

					$headers = array(
						//'subject' =>$subject,
						'to' => $to,
						'from' => $from,
					);
				} else {
					$headers = array(
					//'subject' => $subject,
					'to' => $to,
					//'cc' => $toc,
					//'bcc' => $bcc,
					'from' => $from,
					);
					if ($toc) {
						$headers['cc'] = $toc;
					}
					if ($bcc) {
						$headers[bcc]	= $bcc;
					}
				}
				if (!$to) {
					unset($headers['to']);
				}

				//print_r($headers);exit();
				//print_r($headers);continue;
				//$body = "heeloo";

				$formatDeDate = "Y-m-d";
				if ($loc->langue == "FR" || !$loc->langue) {
					$formatDeDate = "d-m-Y";
				}



				$variables = array('body' => $body, 'config' => $this->getConfigMailsTable()->getMailConfig($idResidence, $modele->idType, $ligne->idCampagne, $idModele), 'format' => $formatDeDate);


				$htmlViewPart = new ViewModel();
				$htmlViewPart->setTerminal(true)
				->setTemplate('application/reservation/mailbody.phtml')
				->setVariables($variables);

				$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

				//echo $htmlOutput;exit();


				## ajout dans l'historiquue
				//PDF
				$pdfCorp = $pdfHeader = $pdfFooter = "";
				if ($modele->pdf != "") {
					$fieldsPdf = $this->getfields($modele->pdf);
					$fieldsHeader = $this->getfields($modele->pdfHeader);
					$fieldsFooter = $this->getfields($modele->pdfFooter);
					//generer le header,corps, et footer du pdf
					$pdfCorp = $this->getPdfFields($modele->pdf, $fieldsPdf, $ligne, $loc);
					$pdfHeader = $this->getPdfFields($modele->pdfHeader, $fieldsHeader, $ligne, $loc);
					$pdfFooter = $this->getPdfFields($modele->pdfFooter, $fieldsFooter, $ligne, $loc);
				}

				if ($exportListe == "xls" || $exportListe == "pdf") {
					if ($modele->pj) {
						$modele->pj .= "|".$session->listeExportedFile;
					} else {
						$modele->pj = $session->listeExportedFile;
					}
				}

				$logsmail = new Historiquemail();
				$logsmail->emeteur = $from;
				$logsmail->nomEmeteur = $fromName;
				$logsmail->dateEnvoi = date('Y-m-d H:i:s');
				$logsmail->objet = $subject;
				$logsmail->message = $body;
				$logsmail->idModele = $modele->id;
				$logsmail->idLocataire = $loc->id;
				$logsmail->pj = $modele->pj;
				$logsmail->docPJ = $modele->docPJ;
				$logsmail->modelePJ = $modele->modelePJ;
				$logsmail->interface = "Backoffice";

				$logsmail->pdf = $pdfCorp;
				$logsmail->pdfHeader = $pdfHeader;
				$logsmail->pdfFooter = $pdfFooter;
				$logsmail->emailRecepteur = $to ? $to : null;

				//si on les joint au mail ou nn
				if ($nePasJoindre) {
					$logsmail->pj = "";
					$logsmail->docPJ = "";
					$logsmail->modelePJ = "";
				}

				try {
					$message = $mailService->compose($headers, 'application/reservation/mailbody.phtml', $variables);

					//pour le souci d utf8 au sujet du mail
					$message->setEncoding("UTF-8");
					$headers = $message->getHeaders();
					$headers->removeHeader('Content-Type');
					$headers->addHeaderLine('Content-Type', 'text/html; charset=UTF-8');
					$headers->get('Content-Type')->setEncoding('UTF-8');
					//Disposition-Notification-To: abc@hotmail.com
					//X-Confirm-Reading-To: abc@hotmail.com
					//Read-Receipt-To: abc@hotmail.com
					//$headers->addHeaderLine('Disposition-Notification-To', 'ludovic.gerard@iriga-networks.com');
					//$headers->addHeaderLine('X-Confirm-Reading-To', 'ludovic.gerard@iriga-networks.com');
					//$headers->addHeaderLine('Read-Receipt-To', 'ludovic.gerard@iriga-networks.com');
					//print_r($headers);exit();

					$message->setHeaders($headers);
					$message->setSubject($subject);
					$message->setFrom($from, $fromName);
					//print_r($message->getHeaders());exit();
					//echo($message->getBodyText());exit();

					if ($toEmail1) {
						$message->addTo($toEmail1);
					}

					## Ajout replyTo emails
					if($modele->emailReplyTo){
						$emailReplyTo = explode(',', $modele->emailReplyTo);
						$emailReplyTo = array_filter($emailReplyTo);
						$message->addReplyTo($emailReplyTo);
					}


					$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
					$text->type = \Zend\Mime\Mime::TYPE_HTML;

					$mimeMessage1 = new \Zend\Mime\Message();
					$mimeMessage1->addPart($text);

					// $attachFiles = array();
					// $pjToSavePath = array();

					if ($modele->pj || $modele->modelePJ) {
						$pjStatiques = array();
						if ($modele->pj) {
							$pjStatiques = explode('|', $modele->pj);
							$pjStatiques = array_filter($pjStatiques);
						}
						if ($modele->modelePJ) {
							$pjModele = explode('|', $modele->modelePJ);
							$pjModele = array_filter($pjModele);
							$pjStatiques = array_merge($pjStatiques, $pjModele);
						}

						foreach ($pjStatiques as $pj) {
							if (file_exists(getcwd().'/public/docs/pj/'.$pj)) {
								$pjToSavePath[] = getcwd().'/public/docs/pj/'.$pj;
								$pjToZip[$loc->id][] = getcwd().'/public/docs/pj/'.$pj;

								//attachments
								// first create the parts

								$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
								$text->type = \Zend\Mime\Mime::TYPE_HTML;
								//$text->charset = 'utf-8';
								$fileContent = fopen(getcwd().'/public/docs/pj/'.$pj, 'r');
								$attachment = new \Zend\Mime\Part($fileContent);
								$ext = pathinfo($pj, PATHINFO_EXTENSION);
								if ($ext == 'xls') {
									$attachment->type = 'application/octet-stream';
								} elseif ($ext == 'csv') {
									$attachment->type = 'text/csv';
								} else {
									$attachment->type = 'application/pdf';
								}
								$attachment->filename = $pj;
								$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
								// Setting the encoding is recommended for binary data
								$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
								$attachFiles[] = $attachment;
							}
						}
					}

					## ajout document coché depuis l'onglet document de la fiche usager
					if(!empty($liensDocsPJ)) {
						foreach ($liensDocsPJ as $lienpj) {
							if (file_exists(getcwd().'/public'.$lienpj)) {
								$pjToSavePath[] = getcwd().'/public'.$lienpj;

								//attachments
								// first create the parts

								$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
								$text->type = \Zend\Mime\Mime::TYPE_HTML;
								//$text->charset = 'utf-8';

								$fileContent = fopen(getcwd().'/public'.$lienpj, 'r');
								$attachment = new \Zend\Mime\Part($fileContent);

								$ext = pathinfo($lienpj, PATHINFO_EXTENSION);
								$pjName = pathinfo($lienpj, PATHINFO_FILENAME);
								$attachment->type = $tools->getMailAttachmentMimeType($ext);
								//$attachment->type = 'application/pdf';

								$attachment->filename = $pjName;
								$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
								// Setting the encoding is recommended for binary data
								$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
								$attachFiles[] = $attachment;
							}
						}
					}

					if ($modele->docPJ) {
						$pjDocs = explode('|', $modele->docPJ);
						$pjDocs = array_filter($pjDocs);

						foreach ($pjDocs as $pj) {
							if (file_exists(getcwd().'/public/'.$pj)) {
								$pjToSavePath[] = getcwd().'/public/'.$pj;
								$pjToZip[$loc->id][] = getcwd().'/public/'.$pj;

								//attachments
								// first create the parts

								$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
								$text->type = \Zend\Mime\Mime::TYPE_HTML;
								//$text->charset = 'utf-8';

								$fileContent = fopen(getcwd().'/public/'.$pj, 'r');
								$attachment = new \Zend\Mime\Part($fileContent);
								$attachment->type = 'application/pdf';
								$attachment->filename = $pj;
								$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
								// Setting the encoding is recommended for binary data
								$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
								$attachFiles[] = $attachment;
							}
						}
					}


					$fileToDelete = "";
					if ($modele->pdf != "") {
						$file = $this->createPdf($modele, $loc, $ligne);
						$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
						$text->type = \Zend\Mime\Mime::TYPE_HTML;
						//$text->charset = 'utf-8';

						$fileContent = fopen($file, 'r');
						$attachment = new \Zend\Mime\Part($fileContent);
						$attachment->type = 'application/pdf';
						$attachment->filename = $this->removeAccent($modele->objet).".pdf";
						$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
						// Setting the encoding is recommended for binary data
						$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;

						$attachFiles[] = $attachment;
						$fileToDelete = $file;
						$pjToSavePath[] = $file;
						$pjToZip[$loc->id][] = $file;

						// then add them to a MIME message
						//$mimeMessage = new \Zend\Mime\Message();
						//$mimeMessage->setParts(array($text, $attachment));
						//$mimeMessage->addPart( $attachment);

						//$message->setBody($mimeMessage);
					}

					## on joint les modèles de documents
					$modelesDocs = $this->getTableObjet('modeles_email_modeles_docs')->select(array('idModeleMail' => $modele->id));
					$modelesDocsGenerer = array();//pour les save dans le dossier historique
					if ($modelesDocs->count() > 0 || $isFacture || ($callType == 'ficheUsagerCompte' && $typeModeleDoc != '')) {
						if($isFacture || ($callType == 'ficheUsagerCompte' && $typeModeleDoc != '')) {
							$modelesDocsArr = $modelesDocs->count() > 0 ? $modelesDocs : array();
							$mod = new \stdClass();
							if($isFacture || $typeModeleDoc == 'facture') {
								$mod->idModeleDoc = 1;
							} elseif($typeModeleDoc == 'quittance') {
								$mod->idModeleDoc = 4;
							} elseif($typeModeleDoc == 'recu') {
								$mod->idModeleDoc = 2;
							}

							array_push($modelesDocsArr, $mod);
							$modelesDocs = $modelesDocsArr;
						}
						foreach ($modelesDocs as $md) {
							$idModeleDoc = $md->idModeleDoc;

							// on genere le document
							if ($idResa) {
								$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => false, );
								$numFacture = "";
								if(!empty($numFactures[$idResa])) {
									$numFacture = $numFactures[$idResa];
								}
								if($numFacture) {
									$returnUrl = $this->genererModeleDocumentFWD($idResa, $numFacture, $idModeleDoc, $options);
								} else {
									$returnUrl = $this->genererModeleDocument($idResa, "", $idModeleDoc, $options);
								}
								//echo $returnUrl;exit();
								if (file_exists($returnUrl)) {
									$fileName = pathinfo($returnUrl, PATHINFO_FILENAME);
									$fileName .= ".pdf";

									$pjToSavePath[] = $returnUrl;
									$pjToZip[$loc->id][] = $returnUrl;

									$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
									$text->type = \Zend\Mime\Mime::TYPE_HTML;
									//$text->charset = 'utf-8';

									$fileContent = fopen($returnUrl, 'r');
									$attachment = new \Zend\Mime\Part($fileContent);
									$attachment->type = 'application/pdf';
									$attachment->filename = $fileName;
									$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
									// Setting the encoding is recommended for binary data
									$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
									$attachFiles[] = $attachment;
									$modelesDocsGenerer[] = $returnUrl;
								}
							}
						}
					}

					## export listes
					$ModeleListes = $this->getTableObjet('modeles_email_listes')->select(array('idModele' => $modele->id));
					$exportToDelete = array();
					foreach($ModeleListes as $ml) {
						$idListe = $ml->idListe;
						$modeListe = $ml->modeListe;
						if($idListe && $modeListe) {
							$exportListeFile = $this->getExportListeForMail($idListe, $modeListe, $saveFile = true);
							// Fichier généré est enregistré dans /docs/pj
							if($exportListeFile && file_exists(getcwd().'/public/docs/pj/'.$exportListeFile)) {
								$pjToSavePath[] = getcwd().'/public/docs/pj/'.$exportListeFile;
								$exportToDelete[] = getcwd().'/public/docs/pj/'.$exportListeFile;

								$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
								$text->type = \Zend\Mime\Mime::TYPE_HTML;
								//$text->charset = 'utf-8';

								$fileContent = fopen(getcwd().'/public/docs/pj/'.$exportListeFile, 'r');
								$attachment = new \Zend\Mime\Part($fileContent);

								$ext = pathinfo($exportListeFile, PATHINFO_EXTENSION);
								if ($ext == 'xls') {
									$attachment->type = 'application/octet-stream';
								} elseif ($ext == 'csv') {
									$attachment->type = 'text/csv';
								} else {
									$attachment->type = 'application/pdf';
								}

								$attachment->filename = $exportListeFile;
								$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
								// Setting the encoding is recommended for binary data
								$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
								$attachFiles[] = $attachment;
							}
						}
					}


					#####################################################
					if ($nePasJoindre) {
						// on ne joint pas les doc au mail
						$attachFiles = array();//on re initialise
					}
					######################################################


					## Envois de pj groupées
					## si le mode envoyer un seule mails avec pj groupees, on fait l'envois sur le dernier mail
					$zipToSend = '';
					if ($mailUniqueAvecPJGroupe == 1) {
						if ($counter == sizeof($listeIdReservations) - 1) {
							## on lui ajout les pj de toutes les lignes zippé dans un seule fichier
							if (!empty($pjToZip)) {
								$folderToZip = getcwd()."/public/docs/pieces_jointes";
								if (!is_dir($folderToZip)) {
									mkdir($folderToZip);
								}
								$pjsToDelete = array();
								$foldersToDelete = array();
								foreach ($pjToZip as $idLoc => $files) {
									foreach ($files as $file) {
										if (file_exists($file)) {
											$nomPrenom = '';
											if (!empty($locsById[$idLoc])) {
												$nomPrenom = trim($locsById[$idLoc]->nom).'_'.trim($locsById[$idLoc]->prenom);
											}
											$locFolder = trim($nomPrenom)."_".$idLoc;
											if (!is_dir($folderToZip."/".$locFolder)) {
												mkdir($folderToZip."/".$locFolder);
											}
											$filename = pathinfo($file, PATHINFO_FILENAME);
											$ext = pathinfo($file, PATHINFO_EXTENSION);
											$filename = $filename.".".$ext;
											$destination = $folderToZip."/".$locFolder."/".$filename;
											copy($file, $destination);
											$pjsToDelete[] = $destination;
											$foldersToDelete[] = $folderToZip."/".$locFolder;
										}
									}
								}
								$zipToSend = getcwd().'/public/data/pieces_jointes.zip';
								$filter = new \Zend\Filter\Compress(array(
										'adapter' => 'zip',
										'options' => array(
											'archive' => $zipToSend,
										),
									));
								$compressed = $filter->filter($folderToZip);

								## on supprime les pjs dans public/docs/pjtozip
								foreach ($pjsToDelete as $f) {
									$this->deleteFile($f);
								}
								//on supprime les repertoires vides
								foreach ($foldersToDelete as $f) {
									if (is_dir($f)) {
										rmdir($f);
									}
								}

								## on ajoute la pj zip au mail
								$attachFiles = array();
								$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
								$text->type = \Zend\Mime\Mime::TYPE_HTML;
								//$text->charset = 'utf-8';

								$fileContent = fopen($zipToSend, 'r');
								$attachment = new \Zend\Mime\Part($fileContent);
								$attachment->type = 'application/zip';
								$attachment->filename = "pieces_jointes.zip";
								$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
								// Setting the encoding is recommended for binary data
								$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
								$attachFiles[] = $attachment;
							}
						} else {
							$counter++;
							continue;
						}
					}
					## Fin envois pj groupées


					if (sizeof($attachFiles) > 0) {
						$mimeMessage = new \Zend\Mime\Message();
						$mimeMessage->addPart($text);
						foreach ($attachFiles as $thisAttachment) {
							$mimeMessage->addPart($thisAttachment);
						}
						$message->setBody($mimeMessage);
					} else {
						$message->setBody($mimeMessage1);
					}

					//echo $message->getBodyText();exit();

					######## stockage dans Housing #######
					if ($stockerPJ) {
						foreach ($pjToSavePath as $fichier) {
							$source = $fichier;
							if (!is_dir(getcwd()."/public/docs/locataires/".$loc->id)) {
								mkdir(getcwd()."/public/docs/locataires/".$loc->id);
							}
							if (!is_dir(getcwd()."/public/docs/locataires/".$loc->id."/mailing")) {
								mkdir(getcwd()."/public/docs/locataires/".$loc->id."/mailing");
							}
							$filename = pathinfo($fichier, PATHINFO_FILENAME);
							$ext = pathinfo($fichier, PATHINFO_EXTENSION);
							$filename = $filename.".".$ext;
							$destination = getcwd()."/public/docs/locataires/".$loc->id."/mailing/".$filename;
							copy($source, $destination);
						}
					}

					//exit();
					if ($simulerEnvois != 1) {
						if (!$isBOEnvoisOnly) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to idModele=$idModele from=$from cc=".(is_array($toc) ? implode(',', $toc) : '')." bcc=".(is_array($bcc) ? implode(',', $bcc) : '')." idModele=$idModele : avantSend");
							try {
								$mailService->send($message);
								//$session->sent = $session->sent + 1;

								if ($to) {
									$msg .= "Email envoye : ".$to."<br />";
								} else {
									$msg .= "Email destinataire vide pour ".$loc->nom." ".$loc->prenom."<br /> ";
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to Exception=".$ex->getMessage());
							}

							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to idModele=$idModele : apresSend");
							$idHist = $this->getHistoriquemailTable()->save($logsmail);
							## partie save en html
							$tools->saveMailEnHTML($loc->id, $bodyHisto, $modele->nomModele, $fileToDelete, $idHist, '', array('modelesDocsGenerer' => $modelesDocsGenerer));//fileToDelete => pdf
						}

						##envois de mail au utilisateurs WL si choisi

						if (!empty($usersEmail)) {
							foreach ($usersEmail as $user_id => $user_email) {
								$message->setTo($user_email);
								if (!$isBOEnvoisOnly) {
									$message->setCc(array());
								}
								if (!$isBOEnvoisOnly) {
									$message->setBcc(array());
								}

								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$user_email idModele=$idModele from=$from cc=".(is_array($toc) ? implode(',', $toc) : '')." bcc=".(is_array($bcc) ? implode(',', $bcc) : '')." idModele=$idModele : avantSend");

								$mailService->send($message);

								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$user_email idModele=$idModele : apresSend");
								$to = $user_email;

								$msg .= "Email envoye: ".$user_email."<br />";

								##save histo users
								$histoArr = get_object_vars($logsmail);
								$histoArr['idUser'] = $user_id;
								unset($histoArr['idLocataire']);
								if (is_numeric($user_id)) {
									$idHis = $this->getHistoriqueMailUsersTable()->saveHistoMailUsers($histoArr);
									$tools->saveMailEnHTML($user_id, $body, $modele->nomModele, $fileToDelete, $idHis, 'users', array('modelesDocsGenerer' => $modelesDocsGenerer));//fileToDelete => pdf
								} else {
									//on le save en historique normal
									unset($histoArr['idUser']);
									$histoArr['email'] = $user_email;
									$log = new Logs();
									$log->dateOperation = date('Y-m-d H:i:s');
									$log->idGestionnaire = $gestId;
									$log->operation = "Export liste : envoi de mail à un tier";
									$log->dataBefore = array();
									$log->dataAfter = $histoArr;
									$log->tableName = "mailing";
									$log->idReservation = null;
									$log->idLocataire = null;
									$this->getLogsTable()->saveLogs($log);
								}
							}
						}
					}

					## on supprime la pj dynamique

					if ($fileToDelete) {
						fclose($fileContent);
						$this->deleteFile($fileToDelete);
					}

					if ($zipToSend != '' && file_exists($zipToSend)) {
						fclose($fileContent);
						$this->deleteFile($zipToSend);
					}

					if(!empty($exportToDelete)) {
						foreach($exportToDelete as $f) {
							$this->deleteFile($f);
						}
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to Exception=".$ex->getMessage());
					$msg .= "Email en erreur : ".$to." ".$ex->getMessage()."<br />";
				}

				if ($codeType && substr($codeType, 0, 13) == 'doc_a_signer_') {
					## Demande de signature d'un document : le type de mail contient le modèle de document en suffixe
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					try {
						$codeModele	= substr($codeType, 13);
						$params	= [
							'idResa'	=> $idResa,
							'codeModele'	=> $codeModele,
							];
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to idModele=$idModele codeType=$codeType : lancement de signature : params=".json_encode($params));
						$erreurs	= $this->lancerSignatureDocumentResa($params);
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to idModele=$idModele codeType=$codeType : lancement de signature : erreurs=".json_encode($erreurs));
						if ($erreurs) {
							$msg .= "Email en erreur : ".$to." dans le lancement de la signature d'un document ERR=".json_encode($erreurs)."<br />";
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$to lancerSignatureDocument Exception=".$ex->getMessage());
						$msg .= "Email en erreur : ".$to." dans le lancement de la signature d'un document ERR=".$ex->getMessage()."<br />";
					}
					if ($session->total > 2) {
						## Bidouille AAK pour éviter les API rate limit
						sleep(60);
						## Bidouille AAK pour éviter les API rate limit
					}
				}

				$counter++;

			}
			//fin envoi

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : msg=$msg error=$error");

			//enregistrement des email dans la session
			$session->listeMailing = $listeEnvois;
			$session->finish = 1;


			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
					->setTemplate('reservation/liste/envoyer')
					->setVariables(array(
						'msg' => $msg,
						'error' => $error,
						'liste' => $listeEnvois,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						'msg' => utf8_encode($msg),
						'simulerEnvois' => $simulerEnvois,
			//'htmlOP'=>$htmlOutput,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	private function getSelectValTraduction($where = array())
	{
		$ligneTraduit = $this->getTraductionTable()->fetchBy($where)->current();
		$textTraduit = "";
		if ($ligneTraduit) {
			$textTraduit = $ligneTraduit->textTraduit;
		}
		return $textTraduit;
	}

	public function envoyerMail($idResa, $type = 0, $idModele = 0, $options = array())
	{
		$msg = "";


		//on bloque
		//return false;

		$codeModele = !empty($options['code']) ? $options['code'] : null;
		$isAdmin = false;//envois au admin et pas le locataire
		if ($codeModele) {
			$typeEmail = $this->getTableObjet('type_email')->select(array('code' => $codeModele))->current();
			if ($typeEmail) {
				$type = $typeEmail->id;
				$isAdmin = $typeEmail->isAdmin == 1 ? true : false;
			}
		}

		if ((!$type || $type == 0) && !$idModele) {
			return false;
		}

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa");

		if ($idResa == 0) {
			$msg = "Id non fourni";
		} else {
			//$resa = $this->getResaTable()->getListe($idResa)->current();
			//if (!empty($options['fromTabletteEdl'])) {
			$resa = $this->getTableObjet('reservations')
				->select(array('id' => $idResa))->current();//on perd les infos locataire si on utlise que cette methode
			//}
			$loc = $this->getLocataireTable()->getLocataire($resa->idLocataire, false);
			$resa = $this->getResaTable()->getListePourMail($idResa, $loc->langue)->current();

			//on cherche les tarifs par defaut de la campagne d abord
			$tarifsDefault = $this->getTableObjet("tarifs")->select(array('idTypeLogement' => $resa->idTypeLogementAttribue, 'idCampagne' => $resa->idCampagne, 'default' => '1'))->current();

			if ($tarifsDefault) {
				if ($tarifsDefault->loyer) {
					$resa->loyerTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->loyer);
				}
				if ($tarifsDefault->montantCaution) {
					$resa->cautionTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->montantCaution);
				}
				if ($tarifsDefault->fraisGestion) {
					$resa->fraisDossierTypeLogementAttribue = sprintf("%.2f", $tarifsDefault->fraisGestion);
				}
			} else {
				$resa->loyerTypeLogementAttribue = '';
				$resa->cautionTypeLogementAttribue = '';
				$resa->fraisDossierTypeLogementAttribue = '';
			}

			$choixR = $this->getChoixTable()->getResaResidence($idResa, $resa->idTypeLogementAttribue);
			if ($choixR) {
				$resa->residence = $choixR->residence;
			}

			$tarif = $this->getChoixTable()->getChoixTarifs($idResa, $resa->idTypeLogementAttribue);
			if ($tarif) {
				if ($tarif->loyer) {
					$resa->loyerTypeLogementAttribue = sprintf("%.2f", $tarif->loyer);
				}
				if ($tarif->montantCaution) {
					$resa->cautionTypeLogementAttribue = sprintf("%.2f", $tarif->montantCaution);
				}
				if ($tarif->fraisGestion) {
					$resa->fraisDossierTypeLogementAttribue = sprintf("%.2f", $tarif->fraisGestion);
				}
			}

			##residence
			if ($resa->idLogement) {
				$resid = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
				if ($resid) {
					$residence = $this->getResidencesTable()->getResidence($resid->idResidence);
					if ($residence) {
						$resa->adresseResidence = $residence->adresse;
						$resa->codePostalResidence = $residence->codePostal;
						$resa->villeResidence = $residence->ville;
						$resa->ribSite = $residence->ribSite;
						$resa->bicSite = $residence->bicSite;
					}
				}
			}


			//ajout code reservation attribué au locataire
			if ($loc && $loc->idCode && $loc->idCode != $resa->idCode) {
				//on vérifie si le idCode du locataire est attribué
				$codeLoc = $this->getCodeTable()->getCode($loc->idCode);
				if ($codeLoc && $codeLoc->idEtat == 2) {
					$resa->codeReservation = $codeLoc->code;
				}
			}

			//mail
			//$lastId = 18;//for testing

			$modeleObj = new Modelesmail();
			$modele = $this->getModelesmailTable()->getModeleByTypeAndLangue($type, $loc->langue);
			if (!$type && $idModele) {
				$modele = $this->getModelesmailTable()->getModele($idModele);
			}

			if (!$modele) {
				//si le modele pas trouve avec la langue du locataire, on cherche la langue par defaut des modeles FR
				$modele = $this->getModelesmailTable()->getModeleByTypeAndLangue($type, 'FR');
				if (!$modele) {
					return false;
				}
			}

			## on cherche le modele de la campage
			$modeleCamp = $this->getModelescampagneTable()->getModele($resa->idCampagne, $modele->id);

			if ($modeleCamp) {
				$modele = $modeleObj->mergeWithCampage($modele, $modeleCamp);
			} elseif (!$isAdmin && $resa->idCampagne) {
				$confCampagne = $this->getTableObjet('modes_campagne')->select(array('idCampagne' => $resa->idCampagne))->current();
				if ($confCampagne && $confCampagne->NePasEnvoyerMailsGeneraux == '1') {
					//on a pas le mail campagne, et le param NePasEnvoyerMailsGeneraux = 1 => on envois pas le mail
					return false;
				}
			}

			## Envois de mail à tout les users de profil lié au modèle
			$pRows = $this->getTableObjet('modeles_email_profile_envois')->select(array('idModele' => $modele->id));
			$usersEmailCopie = array();
			$usersEmailCopieCachee = array();
			$usersEmail = array();
			foreach($pRows as $pRow) {
				$users = $this->getUserTable()->fetchByProfil($pRow->idProfile);
				foreach ($users as $u) {
					if($pRow->typeEnvois == 'dest') {
						$usersEmail[$u->user_id] = $u->email;
					} elseif($pRow->typeEnvois == 'copie') {
						$usersEmailCopie[$u->user_id] = $u->email;
					} elseif($pRow->typeEnvois == 'copieCachee') {
						$usersEmailCopieCachee[$u->user_id] = $u->email;
					}
				}
			}

			//durree relance

			$params = $this->getConfigurationTable()->getConfig(1);

			$optionPerdue = '3';//+3 jours pardefaut
			if ($params->option_perdue) {
				$optionPerdue = $params->option_perdue;
			}

			//on recupère les codes des champs du corps de l'email

			$fields = $this->getfields($modele->corps);
			$langue = $loc->langue == "UK" ? "en_US" : "fr_FR";

			## choix de type logement
			$nbrChoix = $this->getChoixTable()->getChoixDeReservation($idResa);
			$idResidencePremierChoix = null;
			if ($nbrChoix->count() > 0) {
				for ($s = 1;$s <= $nbrChoix->count();$s++) {
					$c = $this->getChoixTable()->getChoixByResaNumero($idResa, $s);
					if ($c) {
						$vr = "typeLogement".$s;
						$resa->$vr = $langue == "en_US" ? $c->typeLogementEn : $c->typeLogement;
						$resa->$vr = utf8_decode($resa->$vr);
						if ($s == 1) {
							if ($c->idResidence) {
								$idResidencePremierChoix = $c->idResidence;
							} else {
								$rc = $this->getChoixTable()->getResaResidence($c->idReservation, $c->idTypeLogement);
								if ($rc) {
									$idResidencePremierChoix = $rc->idResidence;
								}
							}
						}
					}
				}
			}
			## fin choix de type de logement

			$vals = array();
			$body = $modele->corps;
			$bodyHisto = $body;
			$locArray = array();
			foreach ($fields as $row) {
				$valeur = $resa->$row;
				if ($row == "civilite") {
					if ($valeur == 2) {
						$valeur = isset($loc->langue) && $loc->langue == "UK" ? "Mrs" : "Mme";
					} else {
						$valeur = isset($loc->langue) && $loc->langue == "UK" ? "Mr" : "M";
					}
				}

				if ($row == "civilite") {
					if (is_numeric($valeur)) {
						$tblCiv = $this->getTable('civilites');
						$civRes = $tblCiv->select(array('id' => $valeur))->current();
						if ($civRes) {
							$trad = $this->getSelectValTraduction(array('idLigne' => $valeur, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
							$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civRes->nomEn : $civRes->nom;
							if ($trad) {
								$valeur = $trad;
							}
						}
					} else {
						$civ = $resa->civilite;
						$civEn = $resa->civiliteEn;

						$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civEn : $civ;
						if (is_numeric($loc->civilite)) {
							$trad = $this->getSelectValTraduction(array('idLigne' => $loc->civilite, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
							if ($trad) {
								$valeur = $trad;
							}
						}
					}
				}
				if ($row == "paysLocataire") {
					$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idPays, 'codeLangue' => $langue, 'tableReference' => 'pays'));
					if ($trad) {
						$valeur = $trad;
					}
				}
				if ($row == "nationaliteLocataire") {
					$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idNationalite, 'codeLangue' => $langue, 'tableReference' => 'pays'));
					if ($trad) {
						$valeur = $trad;
					}
				}

				if ($row == "dateNow") {
					$valeur = date('Y-m-d');
				}
				if ($row == "dateOptionPerdue") {
					$dateOption = $resa->dateOption;

					if (date('Y', strtotime($dateOption)) < 2000) {
						$dateOption = date('Y-m-d');
					}

					$valeur = date('Y-m-d', strtotime($dateOption." + $optionPerdue day"));
				}

				##### added le 22-06-2017
				if ($row == "typeLogementAttribue" && $loc->langue == "UK" && $resa->typeLogementAttribueEn != "") {
					$valeur = $resa->typeLogementAttribueEn;
				}

				if ($row == "delaiPaiement") {
					$valeur = $params->delaiPaiement;
				}

				if ($row == "totalFrais") {
					//on cherche les lignes de compte à payer
					$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa));
					$montant = 0;
					foreach ($comptes as $c) {
						if ($c->solde > 0) {
							$montant += $c->solde;
						}
					}
					$valeur = sprintf("%.2f", $montant);
				}
				//on cherche dans la pile pour le modele refus
				//if($type == 14){
				$pile = $this->getTableObjet('pile_paiement')->select(array('idReservation' => $idResa))->current();
				if ($pile) {
					if ($row == 'msgErreur') {
						$valeur = $pile->msgErreur;
					}
					if ($row == 'datePaiementFrais' && $pile->dateRefus) {
						$delaiPaiement = $params->delaiPaiement;
						$valeur = date('Y-m-d', strtotime($pile->dateRefus." + $delaiPaiement day"));
					}
				}
				//}

				#####

				//pour changer le format de date
				if (substr($row, 0, 4) == "date") {
					if ($loc->langue == "FR" || !$loc->langue) {
						if ($valeur) {
							$valeur = date('d-m-Y', strtotime($valeur));
						}
					}
				}

				//partie champs dynamique
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				if ($this->getChampsTable()->isDynamique($row)) {
					if (!$locArray) {
						$locArray = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($loc->id, $adapter, $idResa, 0, true);
					}
					if ($row != "libre_residence_cao") {
						$valeur = !empty($locArray[$row]) ? $locArray[$row] : "";
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
					}
				}
				if (substr($row, 0, 19) == "libre_residence_cao") {
					if (!$locArray) {
						$locArray = $this->getLocatairesTable()->getAllInfosDynamiqueForListe($loc->id, $adapter, $idResa, 0, true);
					}
					$idResidenceCao	= $locArray['libre_residence_cao'];
					if ($idResidenceCao) {
						if (!$residenceCao || $residenceCao->id != $idResidenceCao) {
							$residenceCao = $this->getResidencesTable()->getResidence($idResidenceCao);
						}
						if ($residenceCao) {
							if ($row == "libre_residence_cao") {
								$valeur = $residenceCao->nom;
							} elseif ($row == "libre_residence_cao_adresse") {
								$valeur = $residenceCao->adresse;
							} elseif ($row == "libre_residence_cao_codePostal") {
								$valeur = $residenceCao->codePostal;
							} elseif ($row == "libre_residence_cao_ville") {
								$valeur = $residenceCao->ville;
							} elseif ($row == "libre_residence_cao_iban") {
								$valeur = $residenceCao->ribSite;
							} elseif ($row == "libre_residence_cao_bic") {
								$valeur = $residenceCao->bicSite;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] fieldRow=".json_encode($row)." valeur=$valeur");
				}


				//ne pas afficher la photo si le statut est accepté
				if ($row == 'photo' && $loc->photo) {
					$valeur = "";
					if ($loc->statutPhoto == 2) {
						$valeur = "";
					} else {
						$valeur = $this->getGlobalHelper()->getChampTranslation('photo', $resa->idCampagne, $loc->langue == 'UK' ? 'en_US' : 'fr_FR');
					}
				}
				if ($row == "certificatAssur" && $valeur) {
					if ($ligne->statutAssur == 2) {
						$valeur = "";
					} else {
						$valeur = $this->getGlobalHelper()->getChampTranslation('certificatAssur', $resa->idCampagne, $loc->langue == 'UK' ? 'en_US' : 'fr_FR');
					}
				}

				$valeur = nl2br($valeur);
				$valeur = htmlentities($valeur);//echapper les html entities
				$body = str_replace("%".$row."%", $valeur, $body);

				if ($row == "password") {
					$valeur = '**********';
				}
				$bodyHisto = str_replace("%".$row."%", $valeur, $bodyHisto);
			}

			//echo $body;exit();

			$subject = $modele->objet;
			$from  = $modele->emailFrom;
			$fromName  = $modele->nomFrom;
			$to = $loc->emailHec ? $loc->emailHec : $loc->email;
			$to = trim($to);
			## copie
			$toc = $modele->emailCopie;
			if($toc && !is_array($toc)) {
				$toc = explode(',', $toc);
				$toc = array_filter($toc);
			}
			if(!empty($usersEmailCopie)) {
				if(!$toc && !is_array($toc)) {
					$toc = array();
				}
				$toc = array_merge($toc, $usersEmailCopie);
			}

			## copie cachée
			$tocc = $modele->emailCopieCachee ? explode(',', $modele->emailCopieCachee) : array();

			$toEmail1 = $loc->emailHec ? $loc->email : "";
			$toEmail1 = trim($toEmail1);

			if ($isAdmin && $idResa == -1 && $codeModele == 'caf') {
				$to = $modele->emailCopie;
				$toc = "";
				$toEmail1 = "";
			}

			if (!$to) {
				return false;
			}

			//bcc config
			$tableObj = new Tables('type_email', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$config = $tableObj->getTable()->select(array('id' => '6'))->current();

			$sysBcc = array();
			if ($config->bcc) {
				$sysBcc = explode(',', $config->bcc);
			}


			$bcc = array_merge($tocc, $sysBcc);

			if(!empty($usersEmailCopieCachee)) {
				if(!$bcc && !is_array($bcc)) {
					$bcc = array();
				}
				$bcc = array_merge($bcc, $usersEmailCopieCachee);
			}

			$bcc = array_filter($bcc);

			$idResidence = $resid ? $resid->idResidence : 0;
			if (!$idResidence && $idResidencePremierChoix) {
				$idResidence = $idResidencePremierChoix;
			}

			//on prend l'adresse mail du responsable residence si on a une valeur egale à 'responsableresidence@wheb.fr'
			if($idResidence) {
				$residenceRes = $this->getResidencesTable()->getResidence($idResidence);
				if($residenceRes && $residenceRes->email) {
					//copie
					if(is_array($toc) && !empty($toc)) {
						foreach($toc as $index => $adrEmail) {
							if($adrEmail == 'responsableresidence@wheb.fr') {
								$toc[$index] = $residenceRes->email;
							}
						}
					}
					//copie cachée
					if(is_array($bcc) && !empty($bcc)) {
						foreach($bcc as $index => $adrEmail) {
							if($adrEmail == 'responsableresidence@wheb.fr') {
								$bcc[$index] = $residenceRes->email;
							}
						}
					}
				}
			}

			$mailService = $this->getServiceLocator()->get('MtMail\Service\Mail');

			$headers = array(//'subject' => ( $subject),
							'to' => $to,
							'from' => $from,
			);

			if ($toc) {
				$headers['cc'] = $toc;
			}
			if (!empty($bcc)) {
				$headers['bcc'] = $bcc;
			}

			$formatDeDate = "Y-m-d";
			if ($loc->langue == "FR" || !$loc->langue) {
				$formatDeDate = "d-m-Y";
			}


			$variables = array('body' => $body, 'config' => $this->getConfigMailsTable()->getMailConfig($idResidence, $modele->idType, $resa->idCampagne), 'format' => $formatDeDate);

			//print_r($headers);
			$message = $mailService->compose($headers, 'application/reservation/mailbody.phtml', $variables);
			//exit();
			//pour le souci d utf8 au sujet du mail
			$message->setEncoding("UTF-8");
			$headers = $message->getHeaders();
			$headers->removeHeader('Content-Type');
			$headers->addHeaderLine('Content-Type', 'text/html; charset=UTF-8');
			$headers->get('Content-Type')->setEncoding('UTF-8');

			$message->setHeaders($headers);
			$message->setSubject($subject);
			$message->setFrom($from, $fromName);

			if ($toEmail1) {
				//$message->addTo($to);
				$message->addTo($toEmail1);
			}

			## Ajout replyTo emails
			if($modele->emailReplyTo){
				$emailReplyTo = explode(',', $modele->emailReplyTo);
				$emailReplyTo = array_filter($emailReplyTo);
				$message->addReplyTo($emailReplyTo);
			}

			//echo($message->getBodyText());exit();

			$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
			$text->type = \Zend\Mime\Mime::TYPE_HTML;

			$mimeMessage1 = new \Zend\Mime\Message();
			$mimeMessage1->addPart($text);

			$attachFiles = array();
			$pjToSavePath = array();

			if ($modele->pj || $modele->modelePJ) {
				$pjStatiques = array();
				if ($modele->pj) {
					$pjStatiques = explode('|', $modele->pj);
					$pjStatiques = array_filter($pjStatiques);
				}
				if ($modele->modelePJ) {
					$pjModele = explode('|', $modele->modelePJ);
					$pjModele = array_filter($pjModele);
					$pjStatiques = array_merge($pjStatiques, $pjModele);
				}

				foreach ($pjStatiques as $pj) {
					if (file_exists(getcwd().'/public/docs/pj/'.$pj)) {
						$pjToSavePath[] = getcwd().'/public/docs/pj/'.$pj;

						//attachments
						// first create the parts

						$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
						$text->type = \Zend\Mime\Mime::TYPE_HTML;
						//$text->charset = 'utf-8';

						$fileContent = fopen(getcwd().'/public/docs/pj/'.$pj, 'r');
						$attachment = new \Zend\Mime\Part($fileContent);
						$attachment->type = 'application/pdf';
						$attachment->filename = $pj;
						$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
						// Setting the encoding is recommended for binary data
						$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
						$attachFiles[] = $attachment;
					}
				}
			}

			if ($modele->docPJ) {
				$pjDocs = explode('|', $modele->docPJ);
				$pjDocs = array_filter($pjDocs);

				foreach ($pjDocs as $pj) {
					if (file_exists(getcwd().'/public/'.$pj)) {
						$pjToSavePath[] = getcwd().'/public/'.$pj;

						//attachments
						// first create the parts

						$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
						$text->type = \Zend\Mime\Mime::TYPE_HTML;
						//$text->charset = 'utf-8';

						$fileContent = fopen(getcwd().'/public/'.$pj, 'r');
						$attachment = new \Zend\Mime\Part($fileContent);
						$attachment->type = 'application/pdf';
						$attachment->filename = $pj;
						$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
						// Setting the encoding is recommended for binary data
						$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
						$attachFiles[] = $attachment;
					}
				}
			}


			$fileToDelete = "";
			if ($modele->pdf != "") {
				$file = $this->createPdf($modele, $loc, $resa);
				$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
				$text->type = \Zend\Mime\Mime::TYPE_HTML;
				//$text->charset = 'utf-8';

				$fileContent = fopen($file, 'r');
				$attachment = new \Zend\Mime\Part($fileContent);
				$attachment->type = 'application/pdf';
				$attachment->filename = $this->removeAccent($modele->objet).".pdf";
				$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
				// Setting the encoding is recommended for binary data
				$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;

				$attachFiles[] = $attachment;
				$fileToDelete = $file;
				$pjToSavePath[] = $file;

				if ($type == 16) {
					if (!is_dir(getcwd()."/public/docs/locataires/".$loc->id)) {
						mkdir(getcwd()."/public/docs/locataires/".$loc->id);
					}
					if (!is_dir(getcwd()."/public/docs/locataires/".$loc->id."/uploads")) {
						mkdir(getcwd()."/public/docs/locataires/".$loc->id."/uploads");
					}
					if (!is_dir(getcwd()."/public/docs/locataires/".$loc->id."/uploads/HEBER")) {
						mkdir(getcwd()."/public/docs/locataires/".$loc->id."/uploads/HEBER");
					}
					$dest = getcwd()."/public/docs/locataires/".$loc->id."/uploads/HEBER/".$this->removeAccent($modele->objet).".pdf";

					copy($file, $dest);
				}


				// then add them to a MIME message
				//$mimeMessage = new \Zend\Mime\Message();
				//$mimeMessage->setParts(array($text, $attachment));
				//$mimeMessage->addPart( $attachment);

				//$message->setBody($mimeMessage);
			}

			## on joint les modèles de documents
			$modelesDocs = $this->getTableObjet('modeles_email_modeles_docs')->select(array('idModeleMail' => $modele->id));
			$modelesDocsGenerer = array();//pour les save dans le dossier historique
			if ($modelesDocs->count() > 0) {
				foreach ($modelesDocs as $md) {
					$idModeleDoc = $md->idModeleDoc;

					// on genere le document
					if ($idResa) {
						$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => false, );
						$returnUrl = $this->genererModeleDocument($idResa, "", $idModeleDoc, $options);
						//echo $returnUrl;exit();
						if (file_exists($returnUrl)) {
							$fileName = pathinfo($returnUrl, PATHINFO_FILENAME);
							$fileName .= ".pdf";

							$pjToSavePath[] = $returnUrl;
							$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
							$text->type = \Zend\Mime\Mime::TYPE_HTML;
							//$text->charset = 'utf-8';

							$fileContent = fopen($returnUrl, 'r');
							$attachment = new \Zend\Mime\Part($fileContent);
							$attachment->type = 'application/pdf';
							$attachment->filename = $fileName;
							$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
							// Setting the encoding is recommended for binary data
							$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
							$attachFiles[] = $attachment;
							$modelesDocsGenerer[] = $returnUrl;
						}
					}
				}
			}

			## export listes
			$ModeleListes = $this->getTableObjet('modeles_email_listes')->select(array('idModele' => $modele->id));
			$exportToDelete = array();
			foreach($ModeleListes as $ml) {
				$idListe = $ml->idListe;
				$modeListe = $ml->modeListe;
				if($idListe && $modeListe) {
					$exportListeFile = $this->getExportListeForMail($idListe, $modeListe, $saveFile = true);
					// Fichier généré est enregistré dans /docs/pj
					if($exportListeFile && file_exists(getcwd().'/public/docs/pj/'.$exportListeFile)) {
						$pjToSavePath[] = getcwd().'/public/docs/pj/'.$exportListeFile;
						$exportToDelete[] = getcwd().'/public/docs/pj/'.$exportListeFile;

						$text = new \Zend\Mime\Part(wordwrap($message->getBodyText(), 70, "\r\n"));
						$text->type = \Zend\Mime\Mime::TYPE_HTML;
						//$text->charset = 'utf-8';

						$fileContent = fopen(getcwd().'/public/docs/pj/'.$exportListeFile, 'r');
						$attachment = new \Zend\Mime\Part($fileContent);

						$ext = pathinfo($exportListeFile, PATHINFO_EXTENSION);
						if ($ext == 'xls') {
							$attachment->type = 'application/octet-stream';
						} elseif ($ext == 'csv') {
							$attachment->type = 'text/csv';
						} else {
							$attachment->type = 'application/pdf';
						}

						$attachment->filename = $exportListeFile;
						$attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
						// Setting the encoding is recommended for binary data
						$attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
						$attachFiles[] = $attachment;
					}
				}
			}


			if (sizeof($attachFiles) > 0) {
				$mimeMessage = new \Zend\Mime\Message();
				$mimeMessage->addPart($text);
				foreach ($attachFiles as $thisAttachment) {
					$mimeMessage->addPart($thisAttachment);
				}
				$message->setBody($mimeMessage);
			} else {
				$message->setBody($mimeMessage1);
			}

			$mailService->send($message);
			##envois de mail au utilisateurs WL si choisi
			if (!empty($usersEmail)) {
				foreach ($usersEmail as $user_id => $user_email) {
					$message->setTo($user_email);
					if (!$isBOEnvoisOnly) {
						$message->setCc(array());
					}
					if (!$isBOEnvoisOnly) {
						$message->setBcc(array());
					}

					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$user_email idModele=$idModele from=$from cc=".(is_array($toc) ? implode(',', $toc) : '')." bcc=".(is_array($bcc) ? implode(',', $bcc) : '')." idModele=$idModele : avantSend");

					$mailService->send($message);

					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa to=$user_email idModele=$idModele : apresSend");
					$to = $user_email;

					$msg .= "Email envoye: ".$user_email."<br />";

					##save histo users
					$histoArr = get_object_vars($logsmail);
					$histoArr['idUser'] = $user_id;
					unset($histoArr['idLocataire']);
					if (is_numeric($user_id)) {
						$idHis = $this->getHistoriqueMailUsersTable()->saveHistoMailUsers($histoArr);
						$tools->saveMailEnHTML($user_id, $body, $modele->nomModele, $fileToDelete, $idHis, 'users', array('modelesDocsGenerer' => $modelesDocsGenerer));//fileToDelete => pdf
					} else {
						//on le save en historique normal
						unset($histoArr['idUser']);
						$histoArr['email'] = $user_email;
						$log = new Logs();
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = 0;
						$log->operation = "Envois de mail au utilisateurs WL";
						$log->dataBefore = array();
						$log->dataAfter = $histoArr;
						$log->tableName = "mailing";
						$log->idReservation = null;
						$log->idLocataire = null;
						$this->getLogsTable()->saveLogs($log);
					}
				}
			}
			//return true;

			## ajout dans l'historiquue

			$pdfCorp = $pdfHeader = $pdfFooter = "";
			if ($modele->pdf != "") {
				$fieldsPdf = $this->getfields($modele->pdf);
				$fieldsHeader = $this->getfields($modele->pdfHeader);
				$fieldsFooter = $this->getfields($modele->pdfFooter);
				//generer le header,corps, et footer du pdf
				$pdfCorp = $this->getPdfFields($modele->pdf, $fieldsPdf, $resa, $loc);
				$pdfHeader = $this->getPdfFields($modele->pdfHeader, $fieldsHeader, $resa, $loc);
				$pdfFooter = $this->getPdfFields($modele->pdfFooter, $fieldsFooter, $resa, $loc);
			}

			$logsmail = new Historiquemail();
			$logsmail->emeteur = $from;
			$logsmail->nomEmeteur = $fromName;
			$logsmail->dateEnvoi = date('Y-m-d H:i:s');
			$logsmail->objet = $subject;
			$logsmail->message = $body;
			$logsmail->idModele = $modele->id;
			$logsmail->idLocataire = $loc->id;
			$logsmail->pj = $modele->pj;
			$logsmail->docPJ = $modele->docPJ;
			$logsmail->modelePJ = $modele->modelePJ;
			$logsmail->interface = "Portail";

			$logsmail->pdf = $pdfCorp;
			$logsmail->pdfHeader = $pdfHeader;
			$logsmail->pdfFooter = $pdfFooter;
			$logsmail->emailRecepteur = $to ? $to : null;


			$idHist = $this->getHistoriquemailTable()->save($logsmail);
			## partie save en html
			$tools = new Tools();
			$tools->saveMailEnHTML($loc->id, $bodyHisto, $modele->nomModele, $fileToDelete, $idHist, '', array('modelesDocsGenerer' => $modelesDocsGenerer));//fileToDelete => pdf

			//$this->getHistoriquemailTable()->save($logsmail);

			## on supprime la pj dynamique

			if ($fileToDelete) {
				fclose($fileContent);
				$this->deleteFile($fileToDelete);
			}

			if(!empty($exportToDelete)) {
				foreach($exportToDelete as $f) {
					$this->deleteFile($f);
				}
			}


			//$mailService->send($message);
			$msg = "Mail envoyé";
			//fin mail
		}
		return $msg;
	}

	## export mailing liste
	public function exportcsvmailingAction()
	{
		$session = new Container('mailing');
		$listeEnvois = $session->listeMailing;
		$finalData = array();
		foreach ($listeEnvois as $email) {
			$ligne = array($email);
			$finalData[] = $ligne;
		}
		return $this->csvExport('Liste_mailing_'.date('d-m-Y-His').'.csv', array('Email'), $finalData);
	}

	public function pdfAction()
	{

		//ini_set('memory_limit', '640M');
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$this->creerPDF();
	}

	public function testpdfAction()
	{
		$session = new Container('ListIds');
		$blocks = $session->blocks;
		print_r($blocks);
		exit();
	}

	private function creerPDF($saveFile = false)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);

		$urlLogo = $this->getBaseUrl().'/img/'.$conf->logo;

		$session = new Container('ListIds');
		$nbrChamps = $session->nbrChamps;

		$blocks = $session->blocks;

		$format = "A4";
		if ($nbrChamps < 10) {
			$format = "A4";
		} elseif ($nbrChamps <= 20) {
			$format = "A2";
		} else {
			$format = "A1";
		}

		$listeNameComplet = $session->listeNameComplet ? $session->listeNameComplet : "des locataires";

		$pdf = new Mytcpdf("L", "px", $format, true, 'UTF-8', false);
		$pdf->logoWL = $conf->logo;
		//$pdf2 = new \TCPDF("L", "px", $format, true, 'UTF-8', false);
		//$pdf->setPrintFooter(true);
		$pdf->setPrintHeader(true);
		//$pdf2->setPrintHeader(false);

		//$html = $header;

		$html = "";
		$htmlBlocks = array();
		foreach ($blocks as $block) {
			$h = $session->header;
			$h = str_replace('th style="', 'th style="background-color:rgb(214,214,214);', $h);
			$h = str_replace('100px', 'auto', $h);

			$block = str_replace('height:55px', 'height:auto', $block);

			//var_dump( $block);exit();

			$html = '<table width="100%" border="1" cellpadding="4" >';
			$html .= '<thead>';
			$html .= $h;
			$html .= '</thead>';

			$html .= '<tbody>';
			$html .= $block;
			$html .= '</tbody>';

			$html .= '</table>';

			//print_r($html);exit();
			$margin = 60;
			//echo $session->hauteur;
			if ($conf->logo && file_exists(getcwd().'/public/img/'.$conf->logo)) {
				$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP + $margin, PDF_MARGIN_RIGHT);
			}
			//$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM+$margin);

			//$pdf2->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP+100, PDF_MARGIN_RIGHT);
			//$pdf2->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM+100);

			//$pdf2->SetHeaderData('', 0,'' , $header);
			//$pdf2->AddPage();

			//$pdf2->writeHTML($html, true, false, true, false, '');

			//$numPages = $pdf2->getNumPages();
			//$currPage = $pdf2->PageNo();


			$header = '<table width="130%" border="0" cellpadding="0" ><tr>';
			//$header .= '<td><img src="'.$urlLogo.'" alt="test alt attribute" width="160" height="90" border="0" /></td>';
			$header .= '<td width="10%"></td>';
			$header .= "<td width='5%'>Date : ".date('d-m-Y')."</td>";
			$header .= "<td width='70%'><h1 style='text-align:center'>Liste ".$listeNameComplet."</h1></td>";
			$header .= "<td width='15%' style='text-align:right'></td>";
			$header .= "</tr></table>";
			//$header .= '<p></p>';
			// $header .='<table width="100%" border="1" cellpadding="4">';
			// $header .= $session->header;
			// $header.='</table>';
			$pdf->SetHeaderData('', 0, '', $header);
			$pdf->AddPage();
			$pdf->writeHTML($html, true, false, true, false, '');
		}

		$listeName = $session->listeName ? $session->listeName : "Liste";
		$fileName = $listeName.'_'.date('d-m-Y-His').'.pdf';
		if ($saveFile) {
			if (!is_dir(getcwd()."/public/docs")) {
				mkdir(getcwd()."/public/docs");
			}
			if (!is_dir(getcwd()."/public/docs/pj")) {
				mkdir(getcwd()."/public/docs/pj");
			}
			$dossier = getcwd()."/public/docs/pj/";
			$fullPath = $dossier.$fileName;
			$session = new Container('mailing');
			$session->listeExportedFile = $fileName;
			$pdf->Output($fullPath, 'F');
		} else {
			$pdf->Output($fileName, 'D');
		}
	}

	public function ajaxpdfAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$nbrChamps = $request->getPost('nbrChamps');
			$session = new Container('ListIds');
			$session->nbrChamps = $nbrChamps;


			$output = $request->getPost('output');
			$session->output = $output;
			$session->blocks = $request->getPost('blocks');

			$header = $request->getPost('header');
			$session->header = $header;
			$idListe = $request->getPost('idListe', 0);

			$nomListe = $request->getPost('nomListe', '');

			if ($idListe) {
				$liste = $this->getListesTable()->getListe($idListe);
				$session->listeName = $liste ? $this->removeAccent($liste->nom) : "";
				$session->listeNameComplet = $liste ? $liste->nom : "";
			} elseif (trim($nomListe)) {
				$nomListe = trim($nomListe);
				$session->listeName = $this->removeAccent($nomListe);
				$session->listeNameComplet = $nomListe;
			} else {
				$session->listeName = "";
			}

			$session->hauteur = $request->getPost('hauteur');

			$typeAppel = $request->getPost('typeAppel', '');
			//si on appel la focntion depuis l icone attache au mail, dans ce cas on save le document généré
			if ($typeAppel == "mailClick") {
				$rep = $this->creerPDF(true);
			}

			$view = new JsonModel(array(
				'success' => true,
				'op' => '',
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function ajaxcsvbredeaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$session = new Container('ListIds');
			$isResa = $request->getPost('isResa');
			$session->ids = $ids;
			$session->isResa = $isResa;

			$view = new JsonModel(array(
						'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function exportbredeaAction()
	{

		##$bredea = new BredeaSql();

		$conf = $this->getConfigurationTable()->getConfig(1);
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$session = new Container('ListIds');
		$ids = $session->ids;
		$isResa = $session->isResa;

		if (!$isResa) {
			return;
		}

		//$reservations = $this->getResaTable()->getResaBy(array('etat'=>'1'));
		$data = array();

		foreach ($ids as $idResa) {
			$resa = $this->getResaTable()->getResaWithPms($idResa);
			if ($resa) {
				$idLocataire = $resa->idLocataire;
				//$idResa = $resa->id;
				$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $idResa);
				$resa = $this->getResaTable()->getResaWithPms($idResa);
				## choix de type de logement/residence
				$listeChoix = array();
				for ($i = 1; $i <= 3; $i++) {
					$choix = $this->getChoixTable()->getChoixByResaNumero($idResa, $i);
					$c = array();
					if ($choix) {
						$c['idPMS'] = $choix->idPMSDemande;//idPMSDemande
						if ($choix->idResidence) {
							$residence = $this->getResidencesTable()->getResidence($choix->idResidence);
							if ($residence) {
								$c['residence'] = $residence->idPMS;
							}
						}
						$listeChoix[$i] = $c;
					}
				}
				##fin choix de type de logement/residence
			}

			if ($loc && $resa) {
				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					$fieldsLoc = $bredea->locExchangeWL2Bredea($loc);
					$cdemiFields = $bredea->locFcdemiExchangeWL2Bredea($loc);
					$fieldsResa = $bredea->resaExchangeWL2Bredea($resa);
					$fieldsChoix = $bredea->choixExchangeWL2Bredea($listeChoix);

					$data[] = array_merge($fieldsLoc, $fieldsResa, $fieldsChoix, $cdemiFields);

					$bredea->closeConnect();
					$this->pms	= null;
				}
			}
		}

		// code export / csv
		$header = array(
				'demi_nom',
				'demi_prenom',
				'demi_sexe',
				'demi_adr1',
				'demi_adr2',
				'demi_cp',
				'demi_ville',
				'cdemi_port',
				'demi_dtnais',
				'demi_vilnais',
				'demi_sitfam',
				'demi_conna',
				'demi_entdem',
				'demi_sordem',
				'demi_motif',
				'demi_motiv',
				'demi_logactu',
				'demi_activ',
				'demi_etabl',
				'demi_emp_tel',
				'cdemi_emp_adr1',
				'cdemi_emp_adr2',
				'cdemi_emp_date',
				'demi_resso',
				'demi_natre',
				'demi_urgence',
				'demi_urgtel',
				'demi_couvert',
				'cdemi_email',
		);

		$dateFields = array('demi_dtnais', 'demi_entdem', 'demi_sordem', 'cdemi_emp_date');


		$finalData = array();

		foreach ($data as $row) {
			$ligne = array();
			foreach ($header as $key) {
				//if(!empty($row[$key])){
				$valeurCell = trim(str_replace('"', "", $row[$key]));
				if (in_array($key, $dateFields) && strlen($valeurCell) > 6) {
					if (substr($valeurCell, 0, 4) == '1970') {
						$valeurCell = "";
					} else {
						$valeurCell = date('d-m-Y', strtotime($valeurCell));
					}
				}

				$ligne[$key] = isset($valeurCell) ? $valeurCell : "";
				//}
			}
			$finalData[] = $ligne;
		}

		//print_r($finalData);exit();
		return $this->csvExport('Bredea_'.date('d-m-Y').'.txt', $header, $finalData);
	}




	public function exportAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		return $this->createCSV();

		//return $this->csvExport($listeName.'_'.date('d-m-Y-His').'.csv', $header, $finalData);
	}

	private function createCSV($saveFile = false)
	{
		set_time_limit(3600);
		$session = new Container('csv');
		$head = $session->header;
		$output = $session->output;
		$modeExport = $session->modeExport;
		$typesSuivisInFile = $session->typesSuivisInFile;
		$idsModeleStats = $session->idsModeleStats;
		$idListe = $session->idListe;
		$listeName = $session->listeName ? $session->listeName : "Liste";
		$nomListe = $session->nomListe ? $session->nomListe : "";//nom de liste à afficher dans le csv

		$headerTmp = explode('|', $head);
		$header = array();
		foreach ($headerTmp as $h) {
			$header[] = trim(utf8_decode($h));
		}

		$lignes =  explode('|', $output);
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : listeName=$listeName countLignes=".count($lignes));

		$finalData = array();
		$i = 0;
		foreach ($lignes as $row) {
			if ($i % 2 != 0) {
				$row = explode(';', $row);
				$data = array();
				$j = 0;
				foreach ($row as $r) {
					if ($j % 2 != 0) {
						$data[] = trim(utf8_decode($r));
					}
					$j++;
				}
				$finalData[] = $data;
			}
			$i++;
		}

		return $this->outputExcel($finalData, $header, $listeName, $saveFile, $modeExport, $idListe, $typesSuivisInFile, $idsModeleStats, array('nomListe' => $nomListe));
	}

	private function createPdf($modele, $loc, $resa)
	{
		$file = getcwd()."/public/docs/pj/".time().".pdf";
		$pdf = new \TCPDF("", "px", "A4", true, 'UTF-8', false);
		$pdf->setPrintFooter(false);
		$pdf->setPrintHeader(false);
		//$pdf->SetFont('times');

		$pdf->SetAutoPageBreak(true, 10);
		$pdf->SetTopMargin(6);
		$pdf->SetFooterMargin(0);

		$pdf->AddPage();

		$fields = $this->getfields($modele->pdf);
		$fieldsHeader = $this->getfields($modele->pdfHeader);
		$fieldsFooter = $this->getfields($modele->pdfFooter);


		//generer le header,corps, et footer du pdf
		$pdfCorp = $this->getPdfFields($modele->pdf, $fields, $resa, $loc);
		$pdfHeader = $this->getPdfFields($modele->pdfHeader, $fieldsHeader, $resa, $loc);
		$pdfFooter = $this->getPdfFields($modele->pdfFooter, $fieldsFooter, $resa, $loc);


		$conf = $this->getConfigurationTable()->getConfig(1);

		$htmlViewPart = new ViewModel();
		if ($loc->langue == "FR" || !$loc->langue) {
			$htmlViewPart->setTerminal(true)
			->setTemplate('etudiant/index/pdf')
			->setVariables(array(
					'pdf' => $pdfCorp,
					'pdfHeader' => $pdfHeader,
					'pdfFooter' => $pdfFooter,
					'config' => $conf,

			));
		} else {
			$htmlViewPart->setTerminal(true)
			->setTemplate('etudiant/index/pdfEn')
			->setVariables(array(
				'pdf' => $pdfCorp,
				'pdfHeader' => $pdfHeader,
				'pdfFooter' => $pdfFooter,
				'config' => $conf,

			));
		}



		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		$pdf->SetRightMargin(50);
		$pdf->SetLeftMargin(50);

		$pdf->writeHTML($htmlOutput, true, false, true, false, '');

		$pdf->Output($file, 'F');
		return $file;
	}


	private function genererPdfHistorique($loc, $pdfCorp, $pdfHeader, $pdfFooter, $filename = "")
	{
		if (!is_dir(getcwd()."/public/docs/pj")) {
			mkdir(getcwd()."/public/docs/pj");
		}

		if (!is_dir(getcwd()."/public/docs/pj/tmp")) {
			mkdir(getcwd()."/public/docs/pj/tmp");
		}
		if (!is_dir(getcwd()."/public/docs/pj/tmp/".$loc->id)) {
			mkdir(getcwd()."/public/docs/pj/tmp/".$loc->id);
		}

		if (!$filename) {
			$filename = time();
		}

		$file = getcwd()."/public/docs/pj/tmp/".$loc->id."/".$filename.".pdf";
		$pdf = new \TCPDF("", "px", "A4", true, 'UTF-8', false);
		$pdf->setPrintFooter(false);
		$pdf->setPrintHeader(false);
		//$pdf->SetFont('times');

		$pdf->SetAutoPageBreak(true, 10);
		$pdf->SetTopMargin(6);
		$pdf->SetFooterMargin(0);

		$pdf->AddPage();

		$htmlViewPart = new ViewModel();
		if ($loc->langue == "FR" || !$loc->langue) {
			$htmlViewPart->setTerminal(true)
			->setTemplate('etudiant/index/pdf')
			->setVariables(array(
					'pdf' => $pdfCorp,
					'pdfHeader' => $pdfHeader,
					'pdfFooter' => $pdfFooter,

			));
		} else {
			$htmlViewPart->setTerminal(true)
			->setTemplate('etudiant/index/pdfEn')
			->setVariables(array(
				'pdf' => $pdfCorp,
				'pdfHeader' => $pdfHeader,
				'pdfFooter' => $pdfFooter,

			));
		}



		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		$pdf->SetRightMargin(50);
		$pdf->SetLeftMargin(50);

		$pdf->writeHTML($htmlOutput, true, false, true, false, '');

		$pdf->Output($file, 'F');
		return $file;
	}

	private function getPdfFields($pdf, $fields = array(), $resa, $loc)
	{
		$pdfContent = $pdf;
		foreach ($fields as $row) {
			if ($row == "img_right") {
				continue;
			}
			if ($row == "dateNow") {
				if ($loc->langue == "FR" || !$loc->langue) {
					$valeur = date('d-m-Y');
				} else {
					$valeur = date('Y-m-d');
				}
				$pdfContent = str_replace("%".$row."%", $valeur, $pdfContent);
				continue;
			}
			$langue = $loc->langue == "UK" ? "en_US" : "fr_FR";

			$valeur = $resa->$row;
			if ($row == "civilite") {
				if (is_numeric($valeur)) {
					$tbl = new Tables('civilites', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
					$civRes = $tbl->getTable()->select(array('id' => $valeur))->current();
					if ($civRes) {
						$trad = $this->getSelectValTraduction(array('idLigne' => $valeur, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
						$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civRes->nomEn : $civRes->nom;
						if ($trad) {
							$valeur = $trad;
						}
					}
				} else {
					$civ = $resa->civilite;
					$civEn = $resa->civiliteEn;

					$valeur = (isset($loc->langue) && $loc->langue == "UK") ? $civEn : $civ;
					if (is_numeric($loc->civilite)) {
						$trad = $this->getSelectValTraduction(array('idLigne' => $loc->civilite, 'codeLangue' => $langue, 'tableReference' => 'civilites'));
						if ($trad) {
							$valeur = $trad;
						}
					}
				}
			}
			if ($row == "paysLocataire") {
				$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idPays, 'codeLangue' => $langue, 'tableReference' => 'pays'));
				if ($trad) {
					$valeur = $trad;
				}
			}
			if ($row == "nationaliteLocataire") {
				$trad = $this->getSelectValTraduction(array('idLigne' => $loc->idNationalite, 'codeLangue' => $langue, 'tableReference' => 'pays'));
				if ($trad) {
					$valeur = $trad;
				}
			}

			//date option perdue

			//option perdue
			$tableC = new Tables('configuration', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$params = $tableC->getTable()->select()->current();

			$optionPerdue = '3';//+3 jours pardefaut
			if ($params->option_perdue) {
				$optionPerdue = $params->option_perdue;
			}

			if ($row == "dateOptionPerdue") {
				$dateOption = $resa->dateOption;
				if (date('Y', strtotime($dateOption)) < 2000) {
					$dateOption = date('Y-m-d');
				}
				$valeur = date('Y-m-d', strtotime($dateOption." + $optionPerdue day"));
			}

			//pour changer le format de date
			if (substr($row, 0, 4) == "date") {
				if ($loc->langue == "FR" || !$loc->langue) {
					if ($valeur) {
						$valeur = date('d-m-Y', strtotime($valeur));
					}
				}
			}

			//partie champs dynamique
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			if ($this->getChampsTable()->isDynamique($row)) {
				$locArray = $this->getLocataireTable()->getAllInfosDynamiqueForListe($loc->id, $adapter, $resa->id);
				$valeur = !empty($locArray[$row]) ? $locArray[$row] : "";
			}

			$valeur = nl2br($valeur);
			$pdfContent = str_replace("%".$row."%", $valeur, $pdfContent);
		}
		return $pdfContent;
	}

	private function deleteFile($filename)
	{
		if (file_exists($filename)) {
			unlink($filename);
		}
	}

	public function gencafbredeaAction($idApiPms = 1)
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$dateNotifCaf = $request->getPost('dateNotifCaf');
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dateNotifCaf=$dateNotifCaf");
		if (!$dateNotifCaf) {
			$dateNotifCaf	= date('m/Y');
		}

		$success = false;
		$link = array();
		if (!is_dir(getcwd()."/public/data/export/CAFDepart")) {
			if (mkdir(getcwd()."/public/data/export/CAFDepart", 0755, true)) {
				chown(getcwd().'/public/data/export/CAFDepart', 'apache');
				chgrp(getcwd().'/public/data/export/CAFDepart', 'apache');
			}
		}
		$where = [];

		$fileNameCafExport = 'caf_'.date('Y-m-d-H-i');
		if (is_dir(getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport)) {
			// on supprime le dossier ainsi que le fichier zip correspondant
			rmdir(getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport);
		}

		// ainsi que le fichier zip correspondant
		if (is_dir(getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport.'.zip')) {
			rmdir(getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport.'.zip');
		}

		mkdir(getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport, 0777);

		$bredea		= null;

		## Recherche de la présence du PMS-Bredea car sa présence implique un fonctionnement particulier
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$apis	= $this->getApipmsTable()->getAllActiveApiByClass();
		if ($apis["Bredea"]) {
			## Init de la version
			$idApiPms	= reset($apis["Bredea"]);
			$this->initPMS($idApiPms);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiPms=$idApiPms avec Bredea");
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : FILES=".json_encode($_FILES));

		$nbRows	= 0;
		try {
			if ($request->isXmlHttpRequest()) {
				$resaIds = $request->getPost('resas');
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : resaIds=".json_encode($resaIds));
				if ($resaIds) {
					$where = array('reservations.etat' => 6, 'reservations.cafTreated' => 0, 'reservations.cafNum IS NOT NULL', 'reservations.id IN ('.implode(',', $resaIds).')');
				}
			}

			// // GET ALL RESA WITH ETAT = 6 AND GROUP THEM BY SITE
			// if(!empty($where)){
			// 	$reservations = $this->getResaTable()->getResaGroupSite($where);
			// }else{
			// 	//$reservations = $this->getResaTable()->getResaGroupSite(array('reservations.etat' => 6, 'reservations.cafNum IS NOT NULL', 'reservations.cafTreated' => 0));
			// 	$reservations = array();
			// }

			$startMonthDate	= $endMonthDate	= '';
			list($moisNotif, $anneeNotif)	= explode('/', $dateNotifCaf);
			if ($moisNotif && $anneeNotif) {
				$startMonthTS	= strtotime("$anneeNotif-$moisNotif-01");
				if ($startMonthTS) {
					$startMonthDate	= date("Y-m-d", $startMonthTS);
					$endMonthDate	= date("Y-m-t", $startMonthTS);
				}
			}
			if (!$startMonthDate) {
				$startMonthDate = date("Y-m-01");
				$endMonthDate = date("Y-m-t");
			}
			$sql = "SELECT locataires.nom, locataires.prenom, batiments.idResidence, logements.idBatiment, reservations.* FROM reservations LEFT JOIN locataires ON locataires.id = reservations.idLocataire LEFT JOIN logements ON logements.id = reservations.idLogement LEFT JOIN batiments ON batiments.id = logements.idBatiment WHERE (dateDepartTheorique BETWEEN '$startMonthDate' AND '$endMonthDate') AND (cafTreated = 0 OR (cafTreated = 1 AND cafChangementDateDepartTheorique = 1)) AND reservations.archive = '0' AND reservations.etat IN (6,7) AND reservations.cafNum IS NOT NULL AND TRIM(reservations.cafNum) != '' AND idLocataire NOT IN (SELECT idLocataire FROM reservations WHERE idTypeLocataire = 1 AND dateArrivee > NOW())";

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sql=$sql");
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$rows = $adapter->query($sql)->execute();
			$reservationsRows = array();
			foreach ($rows as $row) {
				$reservationsRows[] = $row;
			}

			$nbRows	= count($reservationsRows);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nbRows=$nbRows");
			if ($nbRows > 0) {
				$reservations = array();
				foreach ($reservationsRows as $key => $row) {
					if ($bredea) {
						$codeSite = $row['codeSite'];
						$reservations[$codeSite][] = $row;
					} else {
						$idResidence	= $row['idResidence'];
						if ($idResidence) {
							$reservations[$idResidence][]	= $row;
						}
					}
				}

				// ENREGISTREMENT EMETTEUR
				$en_emetteur = array(
					array('lg' => 2, 'type' => 'N', 'def' => 3),
					array('lg' => 2, 'type' => 'N', 'def' => 42),
					array('lg' => 6, 'type' => 'AN'),
					array('lg' => 5, 'type' => 'AN'),
					array('lg' => 3, 'type' => 'AN', 'def' => ' '),
					array('lg' => 6, 'type' => 'N', 'def' => date('dmy')),
					array('lg' => 24, 'type' => 'AN'),
					array('lg' => 24, 'type' => 'AN'),
					array('lg' => 9, 'type' => 'AN', 'def' => ' '),
					array('lg' => 5, 'type' => 'AN'),
					array('lg' => 5, 'type' => 'AN'),
					array('lg' => 11, 'type' => 'AN'),
					array('lg' => 1, 'type' => 'AN', 'def' => '6'),
					array('lg' => 30, 'type' => 'AN', 'def' => 'MUTATION LOGEMENT MAJ IDENTIF '),
					array('lg' => 27, 'type' => 'AN', 'def' => ' '),
				);

				// ENREGISTREMENT DETAIL
				$en_detail = array(
					array('lg' => 2, 'type' => 'N', 'def' => 6),
					array('lg' => 2, 'type' => 'N', 'def' => 42),
					array('lg' => 6, 'type' => 'AN'),
					array('lg' => 5, 'type' => 'AN'),
					array('lg' => 3, 'type' => 'AN'),
					array('lg' => 5, 'type' => 'AN', 'def' => ' '),
					array('lg' => 13, 'type' => 'AN'),
					array('lg' => 15, 'type' => 'AN'),
					array('lg' => 20, 'type' => 'AN'),
					array('lg' => 12, 'type' => 'AN'),
					array('lg' => 2, 'type' => 'N', 'def' => 1),
					array('lg' => 25, 'type' => 'AN', 'def' => '                         '),
					array('lg' => 6, 'type' => 'N'),
					array('lg' => 6, 'type' => 'N'),
					array('lg' => 38, 'type' => 'AN', 'def' => ' '),
				);

				// ENREGISTREMENT TOTAL
				$en_total = array(
					array('lg' => 2, 'type' => 'N', 'def' => 8),
					array('lg' => 2, 'type' => 'N', 'def' => 42),
					array('lg' => 6, 'type' => 'AN'),
					array('lg' => 5, 'type' => 'AN'),
					array('lg' => 3, 'type' => 'AN'),
					array('lg' => 67, 'type' => 'AN', 'def' => ' '),
					array('lg' => 6, 'type' => 'N'),
					array('lg' => 69, 'type' => 'AN', 'def' => '                                                                     '),
				);
				$success = true;
				// LOOP THEM
				if ($reservations) {
					foreach ($reservations as $keySite => $rows) {
						## Par site
						## ~~~~~~~~
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite rows=".json_encode($rows));
						$result = [];
						// GET SITE
						/*if ($bredea) {
							$siteRow = $bredea->getSitesBySiteCode(str_pad($keySite, 2, 0, STR_PAD_LEFT));
							if (!$siteRow) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite pas de residence avec ce codeSite");
								continue;
							}
							$cafNumEmetteur			= '900'.$siteRow['si_emetteur'];
							$cafCodeBailleur		= $siteRow['csi_bailleur'];
							$cafCodeAgence			= "";
							$cafCodeEtablBailleur		= "30003";
							$cafCodeGuichetBailleur		= "01658";
							$cafNumCompteBailleur		= "00037275738";
							$cafRaisonSocialeCAF		= "CAISSE ALLOCATIONS FAMIL";
							$cafRasionSocialeBailleur	= "ALEGESSEC";
						} else {*/
						$residence = $this->getResidencesTable()->getResidence($keySite);
						if (!$residence) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite pas de residence avec cet Id");
							continue;
						}
						$cafNumEmetteur			= $residence->cafNumEmetteur;
						$cafCodeBailleur		= $residence->cafCodeBailleur;
						$cafCodeAgence			= $residence->cafCodeAgence;
						$cafCodeEtablBailleur		= $residence->cafCodeEtablBailleur;
						$cafCodeGuichetBailleur		= $residence->cafCodeGuichetBailleur;
						$cafNumCompteBailleur		= $residence->cafNumCompteBailleur;
						$cafRaisonSocialeCAF		= $residence->cafRaisonSocialeCAF;
						$cafRaisonSocialeBailleur	= $residence->cafRaisonSocialeBailleur;
						//}

						// CREATE EMETTEUR
						$emetteur = null;
						foreach ($en_emetteur as $key => $value) {
							if (array_key_exists('def', $value)) {
								if ($value['type'] == 'N') {
									$emetteur .= str_pad($value['def'], $value['lg'], 0, STR_PAD_LEFT);
								} else {
									$emetteur .= str_pad($value['def'], $value['lg']);
								}
							} else {
								if ($key == 2) {
									$emetteur .= str_pad($cafNumEmetteur, $value['lg']);
								} elseif ($key == 3) {
									$emetteur .= str_pad($cafCodeBailleur, $value['lg']);
								} elseif ($key == 4) {
									$emetteur .= str_pad($cafCodeAgence, $value['lg']);
								} elseif ($key == 6) {
									$emetteur .= str_pad($cafRaisonSocialeCAF, $value['lg']);
								} elseif ($key == 7) {
									$emetteur .= str_pad($cafRaisonSocialeBailleur, $value['lg']);
								} elseif ($key == 9) {
									$emetteur .= str_pad($cafCodeEtablBailleur, $value['lg']);
								} elseif ($key == 10) {
									$emetteur .= str_pad($cafCodeGuichetBailleur, $value['lg']);
								} elseif ($key == 11) {
									$emetteur .= str_pad($cafNumCompteBailleur, $value['lg']);
								}
							}
						}
						$result[] = $emetteur;

						// LOOP TO CREATE DETAILS
						foreach ($rows as $row) {
							## Par réservation dans keySite
							## ~~~~~~~~~~~~~~~~~~~~~~~~~
							$idResa	= $row['id'];
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite idResa=$idResa row=".json_encode($row));
							if (!$idResa) {
								continue;
							}
							$this->getResaTable()->updateResa(array('cafTreated' => 1), array('id' => $idResa));
							if ($bredea) {
								$dossier = $bredea->getDossiByResa((object) $row);
								if (trim($dossier['dossi_prenom']) == '') {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite idResa=$idResa dossi_prenom est vide");
									continue;
								}
								$dateDepartTheorique	= trim($row['dateDepartTheorique']);
								if (!$dateDepartTheorique || ($dateDepartTheorique == "0000-00-00")) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite idResa=$idResa dateDepartTheorique nul");
									continue;
								}
								$cafNumeroLocataire	= trim($row['cafCode']);
								$cafNumeroAllocataire	= trim($dossier['dossi_noalloc']);
								$cafNomAllocataire	= trim($dossier['dossi_nomcaf']) != '' ? trim($dossier['dossi_nomcaf']) : trim(utf8_encode($dossier['dossi_nom']));
								$cafPrenomAllocataire	= trim(utf8_encode($dossier['dossi_prenom']));
								$cafDateDepart		= date('dmy', strtotime($dateDepartTheorique));
							} else {
								if (!$row['prenom'] || $row['prenom'] == '') {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite idResa=$idResa prenom est vide");
									continue;
								}
								$dateDepart		= $row['dateDepart'];
								if (!$dateDepart || ($dateDepart == "0000-00-00")) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keySite=$keySite idResa=$idResa dateDepart nul");
									continue;
								}
								$cafNumeroLocataire	= trim($row['cafCode']);
								$cafNumeroAllocataire	= trim($row['cafNum']);
								$cafNomAllocataire	= trim($row['nom']);
								$cafPrenomAllocataire	= trim($row['prenom']);
								$cafDateDepart		= date('dmy', strtotime($dateDepart));
							}
							$detail = null;
							foreach ($en_detail as $key => $value) {
								if (array_key_exists('def', $value)) {
									if ($value['type'] == 'N') {
										$detail .= str_pad($value['def'], $value['lg'], 0, STR_PAD_LEFT);
									} else {
										$detail .= str_pad($value['def'], $value['lg']);
									}
								} else {
									// NUM_NAT_EM
									if ($key == 2) {
										$detail .= str_pad($cafNumEmetteur, $value['lg']);
									}
									// CODE_BAI
									elseif ($key == 3) {
										$detail .= str_pad($cafCodeBailleur, $value['lg']);
									}
									// CODE_AGENCE
									elseif ($key == 4) {
										$detail .= str_pad($cafCodeAgence, $value['lg']);
									}
									// NUM_LOC
									elseif ($key == 6) {
										$detail .= str_pad($cafNumeroLocataire, $value['lg'], 0, STR_PAD_LEFT);
									}
									// NUM_ALLOC
									elseif ($key == 7) {
										$detail .= str_pad($cafNumeroAllocataire, $value['lg'], 0, STR_PAD_LEFT);
									}
									// NOM
									elseif ($key == 8) {
										$detail .= str_pad(substr(strtoupper($this->convertAccentedChars($cafNomAllocataire)), 0, $value['lg']), $value['lg']);
									}
									// PRENOM
									elseif ($key == 9) {
										$detail .= str_pad(substr(strtoupper($this->convertAccentedChars($cafPrenomAllocataire)), 0, $value['lg']), $value['lg']);
									}
									// DATE_DEP
									elseif ($key == 12) {
										$detail .= $cafDateDepart;
									}
									// DATE_DEP
									elseif ($key == 13) {
										$detail .= $cafDateDepart;
									}
								}
							}
							$result[] = $detail;
						}

						// CREATE TOTAL
						$total = null;
						foreach ($en_total as $key => $value) {
							if (array_key_exists('def', $value)) {
								if ($value['type'] == 'N') {
									$total .= str_pad($value['def'], $value['lg'], 0, STR_PAD_LEFT);
								} else {
									$total .= str_pad($value['def'], $value['lg']);
								}
							} else {
								// NUM_NAT_EM
								if ($key == 2) {
									$total .= str_pad($cafNumEmetteur, $value['lg']);
								}
								// CODE_BAI
								elseif ($key == 3) {
									$total .= str_pad($cafCodeBailleur, $value['lg']);
								}
								// CODE_AGENCE
								elseif ($key == 4) {
									$total .= str_pad($cafCodeAgence, $value['lg']);
								}
								// TOTAL ENREGISTREMENT
								elseif ($key == 6) {
									$total .= str_pad(count($result) - 1, $value['lg'], 0, STR_PAD_LEFT);
								}
							}
						}
						$result[] = $total;

						// FILE POINTER
						$outputString = implode(PHP_EOL, $result);
						$filename = 'caf_'.$cafNumEmetteur.'_'.$cafCodeBailleur.'_'.uniqid().'.txt';
						$output = getcwd().'/public/data/export/CAFDepart/'.$fileNameCafExport.'/'.$filename;
						$link[] = '/data/export/CAFDepart/'.$fileNameCafExport.'/'.$filename;
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : link=$link output=$output");
						file_put_contents($output, $outputString);
						$success = true;
					}
				} else {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Finalement pas de reservations");
				}
			}
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
		}

		if ($nbRows) {
			// -j (--junk-paths)
			$cmd	= "zip -j -r ".getcwd()."/public/data/export/CAFDepart/".$fileNameCafExport.".zip"." ".getcwd().'/public/data/export/CAFDepart/'.$fileNameCafExport;
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : cmd=$cmd");
			exec($cmd);
		}

		if (!$request->isXmlHttpRequest()) {
			// envoyer mail
			$typeMail = $this->getTableObjet('type_email')->select(array('code' => 'caf'))->current();
			// si le type de mail caf existe et que on a générer au moins 1 fichier .txt
			if ($typeMail && $filesCreated) {
				// récuperation du modele de mail type caf
				$modeleMail = $this->getTableObjet('modeles_email')->select(array('idType' => $typeMail->id))->current();
				if ($modeleMail) {
					$mailSent = $this->envoyerMail(-1, $typeMail->id, $modeleMail->id, array('code' => 'caf', 'fileNameCafExport' => $fileNameCafExport));
					return new JsonModel(array('resp' => "msg: $mailSent"));
					exit();
				}

				return new JsonModel(array('resp' => "Modèle de mail type 'caf' introuvable"));
			}
		} else {
			$view = new JsonModel(array(
					'success' => $success,
					'link' => $link,
				));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function browseCafAction()
	{
		$dir = getcwd()."/public/data/export/CAFDepart";
		$link = '/data/export/CAFDepart/';
		if (!is_dir($dir)) {
			if (mkdir($dir, 0755, true)) {
				chown($dir, 'apache');
				chgrp($dir, 'apache');
			}
		}

		$files = array();
		foreach (scandir($dir) as $file) {
			if (!$this->endsWith($file, '.zip')) {
				continue;
			}
			$files[] = array(
				'creation_date' => filemtime($dir . '/' . $file),
				'file' => $file,
				'link' => $link . $file,
			);
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : files=".json_encode($files));

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/cafbrowser')
		->setVariables(array(
			'files' => $files,
		));
		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		$view = new JsonModel(array(
			'success' => true,
			'htmlOP' => $htmlOutput,
		));
		$view->setTerminal(true);
		return $view;
	}

	public function genererStatsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idListe = $request->getPost('idListe');
			$modeListe = $request->getPost('modeListe');

			$success = false;
			$msg = '';

			// Aller chercher les modèles de la liste
			$tableListes = 'listes';
			if ($modeListe == 'dp') {
				$tableListes = 'dp_listes';
			}

			$modelesListes = $this->getTableObjet('stats_modeles_liste')->select(array('idListe' => $idListe, 'tableListes' => $tableListes))->toArray();

			if (count($modelesListes) > 0) {
				$success = true;
				$modeles = array();
				foreach ($modelesListes as $key => $modeleListe) {
					$mo = $this->getTableObjet('stats_modeles')->select(array('id' => $modeleListe['idModele']))->current();
					$modeles[] = $mo;
				}
			} else {
				$msg = 'Aucun modèle enregistré pour cette liste';
			}

			return new JsonModel(array('success' => $success, 'msg' => $msg, 'modeles' => $modeles));
		}
	}

	public function exportAllFichiersStatsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$request = $this->getRequest();
			$originUrl = $request->getPost('originUrl');

			$urlExtractionStats = $originUrl."/reservation/extractionStats";
			exec('curl -Ss '.$urlExtractionStats);

			return new JsonModel(array('success' => true));
		}
	}

	public function ajaxcsvAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$nbrChamps = $request->getPost('nbrChamps');
			$session = new Container('csv');
			$session->nbrChamps = $nbrChamps;

			$output = $request->getPost('output');
			$session->output = $output;

			$header = $request->getPost('header');
			$session->header = $header;

			$nomListe = $request->getPost('nomListe', '');

			$modeExport = $request->getPost('modeExport', '');
			$idListe = $request->getPost('idListe', 0);
			$idsModeleStats = $request->getPost('idsModeleStats', '');
			$session->modeExport = $modeExport;
			$session->idListe = $idListe;

			$idListe = $request->getPost('idListe', 0);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe nbrChamps=$nbrChamps len_output=".strlen($output)." len_header=".strlen($header));

			if (trim($nomListe)) {
				$session->listeName = trim($nomListe);
				$session->nomListe = trim($nomListe);
			} elseif ($idListe) {
				$liste = $this->getListesTable()->getListe($idListe);
				$session->listeName = $liste ? $this->removeAccent($liste->nom) : "";
				$session->nomListe = $liste ? $liste->nom : "";
			} else {
				$session->listeName = "";
				$session->nomListe = "";
			}

			$typeAppel = $request->getPost('typeAppel', '');
			//si on appel la focntion depuis l icone attache au mail, dans ce cas on save le document généré
			if ($typeAppel == "mailClick") {
				$rep = $this->createCSV(true);
			} elseif ($modeExport == "statsListeDP" || $modeExport == "statsListe" || $modeExport == "statsListeDemandes") {
				$msg = '';
				$success = false;
				// Créer un répertoire à zipper par la suite
				if ($modeExport == "statsListeDP") {
					$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
					$tableListes = "dp_listes";
				} elseif ($modeExport == "statsListe") {
					$liste = $this->getTableObjet('listes')->select(array('id' => $idListe))->current();
					$tableListes = "listes";
				} elseif ($modeExport == "statsListeDemandes") {
					$liste = $this->getTableObjet('demandes_listes')->select(array('id' => $idListe))->current();
					$tableListes = "demandes_listes";
				}

				if (!is_dir(getcwd()."/public/docs/modeles/statsListes/statsZip/")) {
					mkdir(getcwd()."/public/docs/modeles/statsListes/statsZip/");
				}

				$pathStats = getcwd()."/public/docs/modeles/statsListes/";

				// Pour éviter de créer plusieurs fichiers par type de suivis
				$typesSuivisInFile = "";
				$modelesListe = $this->getTableObjet('stats_modeles')->select(array('id' => $idsModeleStats))->toArray();
				$idsModeleStatsGenerer = array();

				if ($modeExport != "statsListeDemandes") {
					$typesSuivisCsv = array();

					foreach ($modelesListe as $key => $modeleListe) {

						## Vérifier que le modèle est bien ajouté à la liste
						$modeleInListe = $this->getTableObjet('stats_modeles_liste')->select(array('idModele' => $modeleListe['id'], 'idListe' => $idListe, 'tableListes' => $tableListes))->current();
						if (!$modeleInListe) {
							continue;
						}

						$idsModeleStatsGenerer[] = $modeleListe['id'];

						## Pour chaque modèle, créer les csv des types de suivis correspondants
						$typesSuivisModele = $this->getTableObjet('stats_modeles_type_suivis')->select(array('idModele' => $modeleListe['id']))->toArray();

						foreach ($typesSuivisModele as $key => $typeSuivisModele) {
							$typeSuivis = $this->getTableObjet('type_suivi')->select(array('id' => $typeSuivisModele['idTypeSuivis']))->current();

							## Vérifier si un fichier a déja été créé
							if (strpos($typesSuivisInFile, $typeSuivis->type) === false) {
								$typesSuivisInFile .= $typeSuivis->type."|";
								$typesSuivisCsv[] = $typeSuivis;
							}
						}
					}

					$session->typesSuivisInFile = $typesSuivisCsv;
					$session->idsModeleStats = $idsModeleStatsGenerer;
				}

				$rep = $this->createCSV(false);

				if ($rep) {
					foreach ($modelesListe as $key => $modeleListe) {

						$modeleInListe = $this->getTableObjet('stats_modeles_liste')->select(array('idModele' => $modeleListe['id'], 'idListe' => $idListe, 'tableListes' => $tableListes))->current();
						if (!$modeleInListe) {
							continue;
						}

						copy($pathStats.$modeleListe['nomFile'], $pathStats."statsZip/".$modeleListe['nomFile']);
					}

					// Ziper ce répertoire et l'envoyer au téléchargement
					$execZip = "rm -f ".$pathStats."statistiques.zip"."|zip -j -r ".$pathStats."statistiques.zip"." ".$pathStats."statsZip";
					exec($execZip);

					if (file_exists($pathStats."statistiques.zip")) {
						$success = true;
						## Vider le répertoire statsZip
						$scanDir = scandir($pathStats."statsZip");
						foreach ($scanDir as $key => $file) {
							if (is_file($pathStats."statsZip/".$file)) {
								unlink($pathStats."statsZip/".$file);
							}
						}
					} else {
						$msg = 'Erreur lors de la compression du dossier';
					}

					return new JsonModel(array('success' => $success, 'msg' => $msg, 'file' => "/docs/modeles/statsListes/statistiques.zip"));
				}
			}

			$view = new JsonModel(array(
						'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function getFicheClienModal()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		// ajout tri onglet
		//$globalHelper = new GlobalHelper($this->getServiceLocator());
		$globalHelper = $this->getGlobalHelper();
		$onglets = $globalHelper->getOngletsFicheClient($idProfile);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/ficheclientmodal')
		->setVariables(array(
			'typesSuivis' => $this->getListeTypesSuivis(),
			'onglets' => $onglets,
			'configOnglets' => $conf->affichageOngletsMenuFicheLocataire ? $conf->affichageOngletsMenuFicheLocataire : 'both',
			'newFicheClientModal' => $conf->newFicheClientModal ? $conf->newFicheClientModal : false,
			'colorNavHeader' => $conf->colorNavHeaderFicheLocataire,
			'colorTextNavHeader' => $conf->colorTextNavHeaderFicheLocataire,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	public function getThemeFields($idTheme)
	{
		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$select = $tableObj->getTable()->getSql()->select();
		$select->where(array('idTheme' => $idTheme));
		$select->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select);

		$theme = array();

		foreach ($themeResult as $t) {
			$theme[] = $t;
		}
		if ($idTheme == 1) {
			//On recupere les champs dynamique
			$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
			foreach ($champsDynamiques as $row) {
				$obj = new \stdClass();
				$obj->code = $row->equivalentSql;
				$obj->id = $row->id;
				$obj->nom = $row->libelle;
				$obj->idType = $row->idType;
				$theme[] = $obj;
			}
		}
		return $theme;
	}

	public function getFieldsListe($mode = "reservation", $params = array())
	{
		$theme = array();
		if ($mode == "reservation" || $mode == "edl" || $mode == "facture" || $mode == "mail") {
			## champs reservations et locataires
			$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$select = $tableObj->getTable()->getSql()->select();
			$select->where(array('afficher' => '1'));
			$select->order(array('nom ASC'));
			$themeResult = $tableObj->getTable()->selectWith($select);

			$theme = array();

			foreach ($themeResult as $t) {
				$t->source = "champs_de_base";
				$theme[$t->equivalentSql] = $t;
			}

			//On recupere les champs dynamique
			$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
			foreach ($champsDynamiques as $row) {
				$obj = new \stdClass();
				$obj->code = $row->equivalentSql;
				$obj->equivalentSql = $row->equivalentSql;
				$obj->id = $row->id;
				$obj->nom = $row->libelle;
				$obj->idType = $row->idType;
				$obj->source = "champs_dynamiques";
				$theme[$row->equivalentSql] = $obj;
			}
		} elseif ($mode == "formulaire") {
			$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

			$select = $tableObj->getTable()->getSql()->select();
			$select->where(array('afficher' => '1', 'table' => 'demandes'));
			$select->order(array('nom ASC'));
			$themeResult = $tableObj->getTable()->selectWith($select);

			$theme = array();

			foreach ($themeResult as $t) {
				$t->source = "champs_de_base";
				$theme[$t->equivalentSql] = $t;
			}
			## champs demandes
			/*$champsDemandes = $this->getTableObjet('champs_demandes')->select(array('active'=>'1','nature'=>'libre'));
			foreach ($champsDemandes as $row) {
				$obj = new \stdClass();
				$obj->code = $row->equivalentSql;
				$obj->equivalentSql = $row->equivalentSql;
				$obj->id = $row->id;
				$obj->nom = $row->libelle;
				$obj->idType = $row->idType;
				$obj->source = "champs_demandes";
				$theme[$row->equivalentSql] = $obj;
			}*/
		} elseif ($mode == "colis") {
			## champs colis
			$champsColis = $this->getTableObjet('champs_colis')->select(array('active' => '1', 'nature' => 'libre'));
			foreach ($champsColis as $row) {
				$obj = new \stdClass();
				$obj->code = $row->equivalentSql;
				$obj->equivalentSql = $row->equivalentSql;
				$obj->id = $row->id;
				$obj->nom = $row->libelle;
				$obj->idType = $row->idType;
				$obj->source = "champs_colis";
				$theme[$row->equivalentSql] = $obj;
			}
		} elseif ($mode == "suivis") {
			$idTypeSuivis = !empty($params['idTypeSuivis']) ? $params['idTypeSuivis'] : null;
			if ($idTypeSuivis) {
				## champs suivis
				$champsSuivis = $this->getTableObjet('champs_suivis')->select(array('active' => '1', 'nature' => 'libre', 'idTypeSuivis' => $idTypeSuivis));
				foreach ($champsSuivis as $row) {
					$obj = new \stdClass();
					$obj->code = $row->equivalentSql;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idType = $row->idType;
					$obj->source = "champs_suivis";
					$theme[$row->equivalentSql] = $obj;
				}
			}
		}

		//On recupere les champs dynamique
		/*$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		foreach ($champsDynamiques as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$theme[$row->equivalentSql] = $obj;
		}*/

		return $theme;
	}

	public function getAllFieldsListe($isResa = 1)
	{
		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$select = $tableObj->getTable()->getSql()->select();
		$select->where(array('afficher' => '1'));
		if ($isResa != 1) {
			$select->where->in('table', array('domiciliations', 'locataires'));
		}
		$select->order(array('nom ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select);

		$theme = array();

		foreach ($themeResult as $t) {
			$t->source = "champs_de_base";
			$t->idType = $t->idTypeHtml;
			$t->sourceListe = $row->sourceListe;
			$theme[$t->equivalentSql] = $t;
		}

		## champs demandes
		$champsDemandes = $this->getTableObjet('champs_demandes')->select(array('active' => '1', 'nature' => 'libre'));
		foreach ($champsDemandes as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$obj->source = "champs_demandes";
			$obj->sourceListe =  $row->sourceListe;
			$obj->nature = $row->nature;
			$obj->options = $row->options;
			$theme[$row->equivalentSql] = $obj;
		}

		## champs colis
		$champsColis = $this->getTableObjet('champs_colis')->select(array('active' => '1', 'nature' => 'libre'));
		foreach ($champsColis as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$obj->source = "champs_colis";
			$obj->nature = $row->nature;
			$obj->sourceListe =  $row->sourceListe;
			$obj->options = $row->options;
			$theme[$row->equivalentSql] = $obj;
		}

		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		foreach ($champsDynamiques as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$obj->sourceListe =  $row->sourceListe;
			$obj->nature = $row->nature;
			$obj->options = $row->options;
			$theme[$row->equivalentSql] = $obj;
		}

		return $theme;
	}

	/*INTER - contrat*/
	private function getEtatIC($resa)
	{
		$tableIC = $this->getTableObjet('intercontrat');

		$etats = $this->getAllEtatIC();

		$rows = array();
		$currentTask = "";
		$isValide = false;
		if ($resa) {
			foreach ($etats as $etat) {
				$row = $tableIC->select(array('idEtat' => $etat->id, 'idReservation' => $resa->id))->current();
				if ($row) {
					//on charge les valeurs specifique a la resa
					$etat->duree = $row->duree;
					$etat->decalage = $row->decalage;
					if (!$row->valide && !$currentTask) {
						$currentTask = $row->idEtat;
					}
					if ($row->valide) {
						$isValide = true;
					}
				}
				$rows[] = $etat;
			}
		} else {
			$rows = $etats;
		}

		if (!$isValide && $resa) {
			//si on trouve pas de tache valide, alors on fait le cacule pour deduire la tache courante
			$etats = $this->getAllEtatIC();
			$periode = 0;
			$dateFinSejour = date('Y-m-d', strtotime($resa->dateDepart." + 1 day"));
			foreach ($etats as $etat) {
				$row = $tableIC->select(array('idEtat' => $etat->id, 'idReservation' => $resa->id))->current();
				$per = $etat->duree;
				if ($row) {
					$per = $row->duree;
				}

				$periode += $per;

				$dateFinSejourPlusPeriodeTS = strtotime($dateFinSejour." + $periode day");
				$now =  strtotime(date('Y-m-d'));
				//echo $etat->nom."  periode $periode finsj $dateFinSejour  ";
				if ($dateFinSejourPlusPeriodeTS > $now) {
					break;
				}
				$currentTask = $etat->id;
			}
		}

		$allRows = array();
		foreach ($rows as $row) {
			$allRows[] = $row;
		}


		return array('etats' => $allRows, 'current' => $currentTask);
	}

	private function isIntercontratOver($resa)
	{
		## mise en IC manulement , donc tant que on a idIntercontrat not null: cad le log est en IC
		if ($resa->idIntercontrat) {
			return false;
		} else {
			return true;
		}
		$tableIC = $this->getTableObjet('intercontrat');
		$etats = $this->getAllEtatIC();
		$periode = 0;
		$dateFinSejour = date('Y-m-d', strtotime($resa->dateDepart." + 1 day"));
		foreach ($etats as $etat) {
			$row = $tableIC->select(array('idEtat' => $etat->id, 'idReservation' => $resa->id))->current();
			$per = $etat->duree;
			if ($row) {
				$per = $row->duree;
			}

			$periode += $per;
		}
		$dateFinSejourPlusPeriodeTS = strtotime($dateFinSejour." + $periode day");
		$now =  strtotime(date('Y-m-d'));
		if ($now > $dateFinSejourPlusPeriodeTS) {
			return true;
		}
		return false;
	}

	private function enIntercontrat($resa)
	{
		// ADDED BY WADIE FROM FATIHA (21/06/2017 15:29) : tu peux l'enlever je pense et mettre juste if($r->etat==6 && $r->idIntercontrat > 0)
		if ($resa->idIntercontrat) {
			return true;
		}
		return false;

		$isOver = $this->isIntercontratOver($resa);
		$changed = $this->getResaTable()->isChanged($resa->id);
		if (!$isOver && !$changed) {
			$tableIC = $this->getTableObjet('intercontrat');
			$etats = $this->getAllEtatIC();
			$periode = 0;
			$dateFinSejour = date('Y-m-d', strtotime($resa->dateDepart." + 1 day"));
			$dateFinSejourTS = strtotime($dateFinSejour);
			$etatsPasser = array();
			foreach ($etats as $etat) {
				$row = $tableIC->select(array('idEtat' => $etat->id, 'idReservation' => $resa->id))->current();
				$per = $etat->duree;
				if ($row) {
					$per = $row->duree;
				}

				$periode += $per;

				$dateFinSejourPlusPeriodeTS = strtotime($dateFinSejour." + $periode day");
				$etatsPasser[] = $etat;
				$now =  strtotime(date('Y-m-d'));
				//if($now <= $dateFinSejourPlusPeriodeTS && $now > $dateFinSejourTS){ // }
				if ($resa->idIntercontrat == $etat->id) {
					return array('etat' => $etat, 'periode' => $periode, 'duree' => $per, 'etatsPasser' => $etatsPasser);
				}
			}
		}
		return false;
	}

	private function getPeriodesIC($resa, $current)
	{
		$periodeDeResa = 0;
		$periodeInitiale = 0;
		$etats = $this->getAllEtatIC();
		foreach ($etats as $row) {
			if ($row->id == $current) {
				break;
			}
			$periodeInitiale += $row->duree;
		}

		$etats =  $this->getEtatIC($resa)['etats'];
		foreach ($etats as $row) {
			if ($row->id == $current) {
				break;
			}
			$periodeDeResa += $row->duree;
		}
		/*if($resa->id == 4){
			echo "pr:$periodeDeResa - pi:$periodeInitiale ** ";
		}*/

		return array('periodeResa' => $periodeDeResa, 'periodeInitiale' => $periodeInitiale);
	}

	private function getAllEtatIC()
	{
		$table = $this->getEtatIntercontratTable();
		$select = $table->getSql()->select();
		$select->order(array('ordre asc'));
		$rows = $table->selectWith($select);
		return $rows;
	}

	private function getPremierEtatIC()
	{
		$table = $this->getEtatIntercontratTable();
		$select = $table->getSql()->select();
		$select->order(array('ordre asc'));
		$row = $table->selectWith($select)->current();
		return $row;
	}

	private function getDernierEtatIC()
	{
		$table = $this->getEtatIntercontratTable();
		$select = $table->getSql()->select();
		$select->where(array('default' => 0));
		$select->order(array('ordre DESC'));
		$row = $table->selectWith($select)->current();
		return $row;
	}

	private function getNextEtatIC($idEtatCourant)
	{
		$table = $this->getEtatIntercontratTable();
		$select = $table->getSql()->select();
		$select->order(array('ordre asc'));
		$resutlSet = $table->selectWith($select);
		$rows = array();
		$i = 0;
		$iCourant = 0;
		foreach ($resutlSet as $row) {
			$rows[$i] = $row;
			if ($idEtatCourant == $row->id) {
				$iCourant = $i;
			}
			$i++;
		}
		if ($iCourant < sizeof($rows) - 1) {
			return $rows[$iCourant + 1];
		}

		return $rows[$iCourant];
	}

	private function getPrevEtatIC($idEtatCourant)
	{
		$table = $this->getEtatIntercontratTable();
		$select = $table->getSql()->select();
		$select->order(array('ordre asc'));
		$resutlSet = $table->selectWith($select);
		$rows = array();
		$i = 0;
		$iCourant = 0;
		foreach ($resutlSet as $row) {
			$rows[$i] = $row;
			if ($idEtatCourant == $row->id) {
				$iCourant = $i;
			}
			$i++;
		}
		if ($iCourant == 0) {
			return $rows[$iCourant + 1];
		}
		if ($iCourant > sizeof($rows) - 1) {
			return $rows[$iCourant + 1];
		}

		return $rows[$iCourant];
	}

	public function getEtatIntercontratTable()
	{
		return $this->getTableObjet('etat_intercontrat');
	}

	public function getIntercontratTable()
	{
		return $this->getTableObjet('intercontrat');
	}

	public function loadTypeLogementResidence($idResidence, $idsTypeLogementDispo)
	{
		$retour = $this->loadBatimentDeResidence($idResidence, $idsTypeLogementDispo);
		$typesOK = $retour['typesOK'];

		return $typesOK;
	}

	private function loadBatimentDeResidence($idResidence, $idsTypeLogement = array())
	{
		## on recupère les types logement par residence
		$types = $this->getTypelogementTable()->fetchByResidence($idResidence);
		$typesBatiments = array();
		$typesOK = array();
		$options = array();
		$avecGenerique	= false;
		foreach ($types as $row) {
			if (in_array($row->idTypeLogement, $idsTypeLogement)) {
				$typesBatiments[$row->idBatiment] = $row->idBatiment;

				## on recharge les types de logement
				$tl = $this->getTypelogementTable()->getTypelogement($row->idTypeLogement);
				if ($tl) {
					if (!empty($tl->nomGenerique)) {
						$avecGenerique	= true;
						$typesOK[$tl->id] = $tl->nomGenerique;
					} elseif ($langue == 'en_US') {
						$typesOK[$tl->id] = !empty($tl->nomEn) ? $tl->nomEn : $tl->nom;
					} else {
						$typesOK[$tl->id] = $tl->nom;
					}
				}
			}
		}
		if ($avecGenerique) {
			## Suppression des doublons de types de logements provoqués par l'utilisation de types génériques
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$typesByName	= array();
			foreach ($typesOK as $tlId => $tlName) {
				$typesByName[$tlName]	= $tlId;
			}
			$typesOK	= array();
			foreach ($typesByName as $tlName => $tlId) {
				$typesOK[$tlId]	= $tlName;
			}
		}

		$options = array();
		if ($idResidence) {
			$rows = $this->getBatimentTable()->getBatimentsDeResidence($idResidence);
			foreach ($rows as $row) {
				if (in_array($row->id, $typesBatiments)) {
					$options[$row->id] = $row->nom;
				}
			}
		}

		return array('listOptions' => $options, 'typesOK' => $typesOK);
	}

	private function loadResidencesDeType($idTypeLogement)
	{
		$residences = $this->getResidencesTable()->fetchAll();

		$residenceOptions = array();

		foreach ($residences as $residence) {
			$typesL = $this->getTypelogementTable()->fetchByResidence($residence->id);
			$allowedResid = false;
			foreach ($typesL as $t) {
				if ($t->idTypeLogement == $idTypeLogement) {
					$allowedResid = true;
				}
			}
			if ($allowedResid) {
				$residenceOptions[$residence->id] = $residence->nom;
			}
		}
		return $residenceOptions;
	}

	public function loadTypeLogementBatiment($idBatiment, $idsTypeLogementDispo)
	{
		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$langue = $translator->getLocale();

		## on recupère les types logement par batiment
		$types = $this->getTypelogementTable()->fetchByBatiment($idBatiment);
		$typesOK = array();
		$avecGenerique	= false;
		foreach ($types as $row) {
			if (in_array($row->idTypeLogement, $idsTypeLogementDispo)) {
				$tl = $this->getTypelogementTable()->getTypelogement($row->idTypeLogement);
				if ($tl) {
					if (!empty($tl->nomGenerique)) {
						$avecGenerique	= true;
						$typesOK[$tl->id] = $tl->nomGenerique;
					} elseif ($langue == 'en_US') {
						$typesOK[$tl->id] = !empty($tl->nomEn) ? $tl->nomEn : $tl->nom;
					} else {
						$typesOK[$tl->id] = $tl->nom;
					}
				}
			}
		}
		if ($avecGenerique) {
			## Suppression des doublons de types de logements provoqués par l'utilisation de types génériques
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$typesByName	= array();
			foreach ($typesOK as $tlId => $tlName) {
				$typesByName[$tlName]	= $tlId;
			}
			$typesOK	= array();
			foreach ($typesByName as $tlName => $tlId) {
				$typesOK[$tlId]	= $tlName;
			}
		}

		return $typesOK;
	}

	private function getBaseUrl()
	{
		$basePath = $this->getRequest()->getBasePath();
		$uri = new \Zend\Uri\Uri($this->getRequest()->getUri());
		$uri->setPath($basePath);
		$uri->setQuery(array());
		$uri->setFragment('');

		$helper = $this->getServiceLocator()->get('ViewHelperManager')->get('ServerUrl');
		$url = $helper->__invoke(false);
		if (substr($uri->getPath(), 0, 1) == '/') {
			$baseUrl = $url . $uri->getPath();
		} else {
			$baseUrl = $url . '/' . $uri->getPath();
		}
		return $baseUrl;
	}


	###########################################################
	######################## PARTIE BREDEA ###########################
	###########################################################

	public function creerDossierBredea($idResa)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if ($conf && $conf->bredea == 1) {
			try {
				$resa = $this->getResaTable()->getListeById($idResa)->current();
				if ($resa->numDossier) {
					return false;
				}

				$idLocataire = $resa->idLocataire;//25;
				//$loc = $this->getLocatairesTable()->getLocataire($idLocataire);
				$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $resa->id);

				//print_r($loc);echo "<br><br>";

				$resa = $this->getResaTable()->getListeById($idResa)->current();

				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);

					$locArr = !is_array($loc) ? get_object_vars($loc) : $loc;
					$resaArr = !is_array($resa) ? get_object_vars($resa) : $resa;

					$locArr = array_filter($locArr);//on supprime les valeurs vide
					$resaArr = array_filter($resaArr);

					$cData = array_merge($locArr, $resaArr);
					$cData['majAdresseFact'] = $conf->majAdresseFact;

					$optionsPrepFacture = array();
					if ($resa->idLogement) {
						$loge = $this->getLogementTable()->getLogement($resa->idLogement);
						if ($loge) {
							if ($loge->loyer > 0) {
								$optionsPrepFacture['loyer'] = $loge->loyer;
							}
							if ($conf->prestaLoyerMultiple == 1) {
								$prestaLoyerMultiple = array();
								if ($conf->prestaLoyerHC && $loge->loyerHC > 0) {
									$prestaLoyerMultiple[$conf->prestaLoyerHC] = $loge->loyerHC;
								}
								if ($conf->prestaCharges && $loge->charges > 0) {
									$prestaLoyerMultiple[$conf->prestaCharges] = $loge->charges;
								}
								if ($conf->prestaComplementLoyer && $loge->complementLoyer > 0) {
									$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $loge->complementLoyer;
								}
								if(!empty($prestaLoyerMultiple)){
									$optionsPrepFacture['prestaLoyerMultiple'] = $prestaLoyerMultiple;
								}
							}
							if ($loge->idPMS) {
								$cData['numeroChambre'] = $loge->idPMS;
							}
						}
					}
					$cData['optionsPrepFacture'] = $optionsPrepFacture;

					##Recup modèle facture et loyer de la grille tarifaire
					$modeleLoyerFacture = $this->getModeleEtLoyerFacture($resa->id);
					if(!empty($modeleLoyerFacture)) {
						if(!empty($modeleLoyerFacture['loyer']) && $modeleLoyerFacture['loyer'] > 0) {
							$cData['loyer'] = $modeleLoyerFacture['loyer'];
							$cData['optionsPrepFacture']['loyer'] = $modeleLoyerFacture['loyer'];
						}
						if(!empty($modeleLoyerFacture['modeleFacture']) && $modeleLoyerFacture['modeleFacture'] != '') {
							$cData['optionsPrepFacture']['modeleFacture'] = $modeleLoyerFacture['modeleFacture'];
						}
					}

					$dossier = $bredea->creerDossier($cData);
					$numDossier = $codeSite = "";
					if ($dossier['numDossier']) {
						$numDossier 	= $dossier['numDossier'];
						$codeSite 	= $dossier['codeSite'];
					}
					if ($numDossier) {
						$upData = array('numDossier' => $numDossier, 'codeSite' => $codeSite);
						$campagneMode = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if (!$campagneMode || $campagneMode->nePasMajPasDeFacture != 1) {
							$upData['pasDeFacture'] = 1;
						}
						if (!$resa->idLogement) {
							$logement = $this->getLogementTable()->getLogementBy(array('idPMS' => $resa->numeroChambre));
							if ($logement) {
								$upData['idLogement'] = $logement->id;
								$upData['numeroChambre'] = $logement->idPMS;
								$this->getLogementTable()->updateLogement(array('idEtat' => '4'), array('id' => $logement->id));
							}
						} else {

							//on passe le logement en occupe
							$this->getLogementTable()->updateLogement(array('idEtat' => '4'), array('id' => $logement->id));
							if (!$resa->numeroChambre) {
								$logement = $this->getLogementTable()->getLogementBy(array('idPMS' => $resa->numeroChambre));
								$upData['numeroChambre'] = $logement->idPMS;
							}
						}

						//on maj les dates theorique
						if (!empty($dossier['dateArriveeTheorique'])) {
							$upData['dateArriveeTheorique'] = date('Y-m-d', strtotime($dossier['dateArriveeTheorique']));
						}
						if (!empty($dossier['dateDepartTheorique'])) {
							$upData['dateDepartTheorique'] = date('Y-m-d', strtotime($dossier['dateDepartTheorique']));

							// changement de flags notification caf
							$upData['cafChangementDateDepartTheorique'] = '1';
						}

						$this->getResaTable()->updateResa($upData, array('id' => $idResa));
						//on genere le code locataire
						$loc = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
						if ($loc && !$loc->codeLocataire) {
							$codeLocataire = 'W'.trim($codeSite).trim($numDossier).substr(str_shuffle('0123456789'), 0, 1);
							$this->getLocatairesTable()->updateLocataire($resa->idLocataire, array('codeLocataire' => $codeLocataire));
							$cDataUp = array('numDossier' => $numDossier, 'codeSite' => $codeSite, 'codeLocataire' => $codeLocataire);
							$bredea->updateIdentifientEcole($cDataUp);
						}

						//echo "Reservation importer IDRESA WL :".$resa->id." NUMDOSSIER $numDossier  LOC ".$loc->nom." ".$loc->prenom."<br>";
						//$i++;
						//exit();
					}
					$bredea->closeConnect();
					$this->pms	= null;
				}

				## copie des fichier vers bredea
				$this->getGlobalHelper()->gererFichiersPMS($idResa, 'ecriture');
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return true;
	}

	## creation de dossier coté bredea depuis fresai
	private function passerEnDossierBredea($idResa, $explicite = false)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		if ($conf && $conf->bredea == 1) {
			try {
				$resa = $this->getResaTable()->getResa($idResa);
				if ($resa->numDossier && !$explicite) {
					return false;
				}

				$idLocataire = $resa->idLocataire;//25;
				//$loc = $this->getLocataireTable()->getLocataire($idLocataire);
				$loc = $this->getLocataireTable()->getAllInfos($idLocataire, $adapter, false, $resa->id);

				//print_r($loc);echo "<br><br>";

				$resa = $this->getResaTable()->getListeById($idResa)->current();

				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);

					$locArr = !is_array($loc) ? get_object_vars($loc) : $loc;
					$resaArr = !is_array($resa) ? get_object_vars($resa) : $resa;

					$locArr = array_filter($locArr);//on supprime les valeurs vide
					$resaArr = array_filter($resaArr);

					$allData = array_merge($locArr, $resaArr);

					$cData = array();
					$cData['dataWL'] = $allData;
					$cData['codeSite'] = $resa->codeSite;
					$cData['numResa'] = $resa->numResa;
					$cData['majAdresseFact'] = $conf->majAdresseFact;

					//on recupere le code logement
					if (!$resa->idLogement) {
						return false;
					}
					$logement = $this->getLogementTable()->getLogement($resa->idLogement);
					$optionsPrepFacture = array();
					if ($logement) {
						$cData['numLog'] = $logement->idPMS;
						if ($logement->loyer > 0) {
							$cData['loyer'] = $logement->loyer;
						}
						if ($logement->loyer > 0) {
							$optionsPrepFacture['loyer'] = $logement->loyer;
						}
						
						if ($conf->prestaLoyerMultiple == 1) {
							$prestaLoyerMultiple = array();
							if ($conf->prestaLoyerHC && $logement->loyerHC > 0) {
								$prestaLoyerMultiple[$conf->prestaLoyerHC] = $logement->loyerHC;
							}
							if ($conf->prestaCharges && $logement->charges > 0) {
								$prestaLoyerMultiple[$conf->prestaCharges] = $logement->charges;
							}
							if ($conf->prestaComplementLoyer && $logement->complementLoyer > 0) {
								$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $logement->complementLoyer;
							}
							if(!empty($prestaLoyerMultiple)){
								$optionsPrepFacture['prestaLoyerMultiple'] = $prestaLoyerMultiple;
							}
						}
						$cData['optionsPrepFacture'] = $optionsPrepFacture;
					} else {
						return false;
					}

					//on verifie le site
					if (!$cData['codeSite']) {
						$r = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						if ($r) {
							$cData['codeSite'] = $r->idPMSResidence;
						} else {
							return false;
						}
					}

					##Recup modèle facture et loyer de la grille tarifaire
					$modeleLoyerFacture = $this->getModeleEtLoyerFacture($resa->id);
					if(!empty($modeleLoyerFacture)) {
						if(!empty($modeleLoyerFacture['loyer']) && $modeleLoyerFacture['loyer'] > 0) {
							$cData['loyer'] = $modeleLoyerFacture['loyer'];
							$cData['optionsPrepFacture']['loyer'] = $modeleLoyerFacture['loyer'];
						}
						if(!empty($modeleLoyerFacture['modeleFacture']) && $modeleLoyerFacture['modeleFacture'] != '') {
							$cData['optionsPrepFacture']['modeleFacture'] = $modeleLoyerFacture['modeleFacture'];
						}
					}


					##ajout dans Bredea
					$return = $bredea->passerEnDossier($cData);
					//$return = array('numDossier'=>'00425','siteDossier'=>'03');//pour test

					$numDossier = $siteDossier = "";
					if (!empty($return)) {
						$numDossier = $return['numDossier'];
						$siteDossier = $return['siteDossier'];
					}

					if ($numDossier) {
						$upData = array('numDossier' => $numDossier);
						$upData['codeSite'] = $siteDossier;
						$upData['typre'] = 'R';
						//$upData['pasDeFacture'] = 1;
						if (!$resa->numeroChambre) {
							if ($logement) {
								$upData['numeroChambre'] = $logement->idPMS;
							}
						}

						//on maj les dates theorique
						if (!empty($return['dateArriveeTheorique'])) {
							$upData['dateArriveeTheorique'] = date('Y-m-d', strtotime($return['dateArriveeTheorique']));
						}
						if (!empty($return['dateDepartTheorique'])) {
							$upData['dateDepartTheorique'] = date('Y-m-d', strtotime($return['dateDepartTheorique']));

							// changement de flags notification caf
							$upData['cafChangementDateDepartTheorique'] = '1';
						}

						$this->getLogementTable()->updateLogement(array('idEtat' => '4'), array('id' => $logement->id));//passe en occuper
						$this->getResaTable()->updateResa($upData, array('id' => $idResa));

						//on genere le code locataire
						$loc = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
						if ($loc && !$loc->codeLocataire) {
							$codeLocataire = 'W'.trim($codeSite).trim($numDossier).substr(str_shuffle('0123456789'), 0, 1);
							$this->getLocatairesTable()->updateLocataire($resa->idLocataire, array('codeLocataire' => $codeLocataire));
							$cDataUp = array('numDossier' => $numDossier, 'codeSite' => $codeSite, 'codeLocataire' => $codeLocataire);
							$bredea->updateIdentifientEcole($cDataUp);
						}

						$log = new Logs();

						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "Bredea - reservation passer en dossier $numDossier $siteDossier";
						$log->dataBefore = array();
						$log->dataAfter = $upData;
						$log->tableName = "Bredea";
						$log->idReservation = $idResa;
						$log->idLocataire = $idLocataire;
						$this->getLogsTable()->saveLogs($log);
					}

					$bredea->closeConnect();
					$this->pms	= null;
				}

				## copie des fichier vers bredea
				$this->getGlobalHelper()->gererFichiersPMS($idResa, 'ecriture');
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return true;
	}

	## creation facture FDD
	private function creerFactureFDD($idResa, $type, $montant, $numTransaction = "")
	{
		## type 3 :FDD(facture + encaiss), 4:Caution(encaiss)
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$loc =  $this->getLocatairesTable()->getLocataire($resa->idLocataire);
		$conf = $this->getConfigurationTable()->getConfig(1);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		## Encaissement sur le compte caution
		if ($type == 4) {
			$typeCompte = "4";
			## Sinon Encaissement sur le compte résident
		} else {
			$typeCompte = "1";
		}

		$typre = $resa->typre ? $resa->typre : 'R';

		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();

					if ($type == 3) {
						## FDD
						$dataFact = array();
						$dataFact['codeSite'] 	= $resa->codeSite;
						$dataFact['numLog'] 	= strtoupper($resa->numeroChambre);
						$dataFact['numDossier']	= $resa->numDossier;
						$dataFact['typre']		= $typre;
						$dataFact['dateFact']	= date('Ymd');
						if ($montant == 110) {
							$dataFact['prestCode']	= array('FR02' => '1');
							$dataFact['prestMontant']	= array('FR02' => $montant);
						} else {
							$dataFact['prestCode']	= array('FR01' => '1');
							$dataFact['prestMontant']	= array('FR01' => $montant);
						}

						$dataFact['isFDD']	= '1';

						## on récupére le numéro de la facture qu'on crée
						$cData['fact_nopiece']	= $bredea->creationFacture($dataFact);

						$log = new Logs();
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "Bredea - creation facture FDD de ".$loc->nom." ".$loc->prenom;
						$log->dataBefore = array();
						$log->dataAfter = $dataFact;
						$log->tableName = "Bredea";
						$log->idReservation = $resa->id;
						$log->idLocataire = $resa->idLocataire;
						$this->getLogsTable()->saveLogs($log);
					}
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return true;
	}


	private function checkDisponibiliteLogementBredea($idResa, $date = "")
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$resa = $this->getResaTable()->getListeById($idResa)->current();

				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql();
					if ($resa->numDossier && $resa->codeSite && $date) {
						$cData = array();
						$cData['numDossier'] = $resa->numDossier;
						$cData['codeSite'] = $resa->codeSite;
						$cData['typre'] = $resa->typre;
						$cData['dateDepart'] = $date;

						$return = $bredea->checkDisponibiliteLogementParDate($cData);
						return $return;
					}

					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return true;
	}

	##Action forwarder depuis un autre controller
	public function updateResaPmsAndSigForwardAction()
	{
		$params	= $this->getEvent()->getRouteMatch()->getParam('params');
		if (!empty($params)) {
			$idResa = $params['idResa'];
			if ($idResa) {
				$this->updateResaPmsAndSig($idResa);
			}
		}
		exit();
	}

	public function updateResaPmsAndSig($idResa)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$cr	= false;
		if ($conf && $conf->bredea == 1) {
			try {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");

				## Lecture de la réservation avec infos PMS et SIG
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$resa = $this->getResaTable()->getResaWithSig($idResa);
				if (!$resa) {
					## Pas de resa trouvée
					## ~~~~~~~~~~~~~~~~~~~
					return $cr;
				}
				$idApiPms		= $resa->idApiPms;
				$idPMS			= $resa->idPMS;
				$numDossier		= $resa->numDossier;//on peut avoir des dossier sans idPMS(numDemande)
				$idApiSig		= $resa->idApiSig;
				$idReservationSig	= $resa->idReservationSig;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa PMS=$idApiPms/$idPMS SIG=$idApiSig/$idReservationSig");
				if ($idApiPms == ApipmsTable::ID_API_NO_PMS) {
					## Cas particulier des résidences sans PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				} elseif ($idPMS || $numDossier) {
					if (!$idApiPms) {
						$idApiPms	= 1;
					}
					if (!is_object($this->pms) || $idApiPms != $this->pms->getIdApiPms()) {
						## Connexion au PMS
						## ~~~~~~~~~~~~~~~~
						try {
							$this->pms	= null;
							$pmsGen	= new PmsGen($adapter, $idApiPms);
							if ($pmsGen) {
								$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
								if (is_object($pms)) {
									$this->pms	= $pms;
								}
							}
							if (!$this->pms) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms injoignable");
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
						}
					}
					if ($this->pms && is_object($this->pms)) {
						try {
							## Traitement en fonction du PMS
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if ($this->pms->getClassName() === "Bredea") {
								$cr	|= $this->updateResaBredea($idResa);
							} elseif ($this->pms->getClassName() === "CeriFoyer") {
								$this->pms->setResaTable($this->getResaTable());
								$this->pms->setPaysTable($this->getPaysTable());
								$cr	|= $this->pms->updateReservationPms($resa);
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
						}
					}
				}

				if (!$idApiSig && ($resa->etat == 3 || $resa->etat == 7)) {
					## Recherche d'interfaces SIG avec transfert à la confirmation des réservations
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$apiSigs	= $this->getApisigTable()->getAllActiveApiWithKey('transmitonconfirm');
					if ($apiSigs) {
						foreach ($apiSigs as $apiSig) {
							$idApiSig	= $apiSig->id;
							if ($idApiSig) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : etatResa=".$resa->etat." idApiSig=$idApiSig");
							}
						}
					}
				}
				if ($idApiSig) {
					if (!is_object($this->sig) || $idApiSig != $this->sig->getIdApiSig()) {
						## Connexion au SIG
						## ~~~~~~~~~~~~~~~~
						try {
							$this->sig	= null;
							$sigGen	= new SigGen($adapter, $idApiSig);
							if ($sigGen) {
								$sig	= $sigGen->connect();
								if (is_object($sig)) {
									$this->sig	= $sig;
								}
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiSig=$idApiSig= exception=".$ex->getMessage());
						}
					}
					if (!$this->sig) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiSig=$idApiSig injoignable");
					} else {
						try {
							## Traitement par le SIG
							## ~~~~~~~~~~~~~~~~~~~~~
							if (strtoupper($this->sig->getClassName()) == "ALTAIR") {
								list($contact, $location, $locationContact)	= $this->sig->createOrUpdateLocationContact($resa);
								$cr	|= ($contact && $location && $locationContact);
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiSig=$idApiSig= exception=".$ex->getMessage());
						}
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
			}
		}
		return $cr;
	}

	## UPDATE INFOS BREDEA
	public function updateResaBredea($idResa)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$resa = $this->getResaTable()->getListeById($idResa)->current();
				$bredea		= null;
				if ($resa->idPMS || $resa->numDossier || $resa->numResa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);
					//$resa =  $this->getResaTable()->getResa($idResa);
					//pour le cas des demande et resai ou on a pas idLogement, on cherche le site via le type logement
					if (!$resa->codeSite) {
						$residenceDuType = $this->getTypelogementTable()->getResidenceDuTypeLogement($resa->idTypeLogementAttribue);
						if ($residenceDuType) {
							$resa->codeSite = $residenceDuType->idPMSResidence;
						}
					}

					$idLocataire = $resa->idLocataire;
					$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $idResa);
					//$loc = $this->getLocatairesTable()->getLocataire($idLocataire);

					## choix de type de logement/residence
					$listeChoix = array();
					for ($i = 1; $i <= 3; $i++) {
						$choix = $this->getChoixTable()->getChoixByResaNumero($idResa, $i);
						$c = array();
						if ($choix) {
							$c['idPMS'] = $choix->idPMSDemande;//idPMSDemande
							if ($choix->idResidence) {
								$residence = $this->getResidencesTable()->getResidence($choix->idResidence);
								if ($residence) {
									$c['residence'] = $residence->idPMS;
								}
							}
							$listeChoix[$i] = $c;
						}
					}

					##fin choix de type de logement/residence

					//infos des select avec idPMS
					$infos = $this->getLocatairesTable()->getInfosSelect($idLocataire, $adapter, $idResa);

					//$bredea = new BredeaSql();
					if (!$resa->dateDepart || substr($resa->dateDepart, 0, 2) == "00") {
						$resa->dateDepart = '0';
					}
					if (!$resa->dateDepartTheorique || substr($resa->dateDepartTheorique, 0, 2) == "00") {
						$resa->dateDepartTheorique = '0';
					}

					//verification changement de date arr et depart an cas de changement de logement
					if ($resa->idNouvelleResa) {
						//on cherche la nouvelle resa pour verifie si les deux resa on le meme dossier
						$nr = $this->getResaTable()->getResa($resa->idNouvelleResa);
						if ($nr && $nr->numDossier == $resa->numDossier) {
							if (!$nr->idNouvelleResa && $nr->dateDepart && substr($nr->dateDepart, 0, 2) != "00") {
								$resa->dateDepart = $nr->dateDepart;//on mis la date depart de la nouvelle resa
								$resa->dateDepartTheorique = null;//on ne maj pas cette valeur dans bredea
							} else {
								$resa->dateDepartTheorique = $resa->dateDepart = null;
							}
						}
						//si la nouvelle resa est en cours de changement on mis la date de depart de la nouvelle resa
						if ($nr && $nr->etat == 15 && $nr->dateDepart) {
							$resa->dateDepart = $nr->dateDepart;
							$resa->dateDepartTheorique = null;//
						}
					}

					if ($resa->idAncienneResa) {
						//on cherche l ancienne resa pour verifie si les deux resa on le meme dossier
						$nr = $this->getResaTable()->getResa($resa->idAncienneResa);
						if ($nr && $nr->numDossier == $resa->numDossier && $nr->dateArrivee) {
							if (!$nr->idAncienneResa) {
								$resa->dateArrivee = $nr->dateArrivee;
								$resa->dateArriveeTheorique = null;
							} else {
								$resa->dateArriveeTheorique = $resa->dateArrivee = null;
							}
						}
					}
					if ($resa->idLogement) {
						$logement = $this->getLogementTable()->getLogement($resa->idLogement);
						if ($logement && $logement->loyer > 0) {
							$resa->loyer1 = $logement->loyer;
						}
						if ($logement) {
							$optionsPrepFacture = array();
							if ($logement->loyer > 0) {
								$optionsPrepFacture['loyer'] = $logement->loyer;
							}
							
							if ($conf->prestaLoyerMultiple == 1) {
								$prestaLoyerMultiple = array();
								if ($conf->prestaLoyerHC && $logement->loyerHC > 0) {
									$prestaLoyerMultiple[$conf->prestaLoyerHC] = $logement->loyerHC;
								}
								if ($conf->prestaCharges && $logement->charges > 0) {
									$prestaLoyerMultiple[$conf->prestaCharges] = $logement->charges;
								}
								if ($conf->prestaComplementLoyer && $logement->complementLoyer > 0) {
									$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $logement->complementLoyer;
								}
								if(!empty($prestaLoyerMultiple)){
									$optionsPrepFacture['prestaLoyerMultiple'] = $prestaLoyerMultiple;
								}
							}
							$resa->optionsPrepFacture = $optionsPrepFacture;
						}
					}


					$return = $bredea->updateReservation($loc, $resa, $listeChoix, $infos);//return true/false


					## maj des dates theoriques
					if ($resa->numDossier) {
						$typeFacturation = $conf->typeFacturation;
						$dateDebutFact = $conf->dateDebutFact;
						$return = $bredea->majDatesFacturation($resa->numDossier, $resa->codeSite, $resa->typre, array('typeFacturation' => $typeFacturation, 'dateDebutFact' => $dateDebutFact));

						//on maj les dates theorique
						$upData = array();
						if (!empty($return['dateArriveeTheorique']) && !$resa->idAncienneResa) {
							$upData['dateArriveeTheorique'] = date('Y-m-d', strtotime($return['dateArriveeTheorique']));
						}
						if (!empty($return['dateDepartTheorique']) && !$resa->idNouvelleResa) {
							$upData['dateDepartTheorique'] = date('Y-m-d', strtotime($return['dateDepartTheorique']));

							// changement de flags notification caf
							$upData['cafChangementDateDepartTheorique'] = '1';
						}

						if (!empty($upData)) {
							$this->getResaTable()->updateResa($upData, array('id' => $idResa));
						}

						## remonte des infos RIB si ils sont à ajour dans bredea et pas dans WL
						$tableVD = $this->getTableObjet('valeurs_dynamiques');
						$champsFormulaireTable = $this->getTableObjet('champs_formulaires');

						$select = $champsFormulaireTable->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where(array('formulaires.idCampagne' => $resa->idCampagne));
						$select->where->like('champs_formulaires.nomXML', 'rib_%');
						$champsRIB = $champsFormulaireTable->selectWith($select);
						if (!empty($champsRIB)) {
							$dataRIB = $bredea->lireRIB(array('numDossier' => $resa->numDossier,
																'codeSite' => $resa->codeSite,
																'typre' => $resa->typre));
							if (!empty($dataRIB)) {
								foreach ($champsRIB as $champ) {
									$valeur = !empty($dataRIB[$champ->nomXML]) ? $dataRIB[$champ->nomXML] : '';
									if ($valeur) {
										$vdRow = $tableVD->select(array('idChamp' => $champ->id, 'idReservation' => $idResa))->current();
										if (!$vdRow || trim($vdRow->valeur) == '') {
											$valeursObj = new Valeurschampdynamique();
											$valeursObj->idChamp = $champ->id;
											$valeursObj->valeur = utf8_encode($valeur);
											$valeursObj->idLocataire = $resa->idLocataire;
											$valeursObj->idReservation = $idResa;
											$valeursObj->statutDoc = null;
											$this->getValeurschampdynamiqueTable()->save($valeursObj);
										}
									}
								}
							}
						}
					}

					$bredea->closeConnect();
					$this->pms	= null;

					## Tentative de recopier les documents
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($resa->numDossier) {
						try {
							## copie des fichier vers bredea
							$this->getGlobalHelper()->gererFichiersPMS($idResa, 'ecriture');
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : gererFichiersPMS idResa=$idResa Exception=".$ex->getMessage());
						}
					}
				} else {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa : impossible d'accéder au PMS");
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}

		return true;
	}

	public function showDossierAction()
	{
		$prefix = (isset($_GET['prefix']) && $_GET['prefix'] != "") ? strtolower($_GET['prefix']) : 'dossi';
		$codeSite = (isset($_GET['codeSite']) && $_GET['codeSite'] != "") ? $_GET['codeSite'] : '';
		$numDossier = (isset($_GET['numDossier']) && $_GET['numDossier'] != "") ? $_GET['numDossier'] : '';

		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
		if ($codeSite && $numDossier) {
			$where = array($prefix.'_nodoss' => $numDossier, 'dossi_site' => $codeSite);
			$dossier = $bredea->getRows('001f'.$prefix, $where);
			print_r($dossier);
		}
		exit();
	}

	public function getReservationPms($idResa)
	{
		// foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 8) as $entry_id => $entry) {
		// if (!$entry['file']) { break; }
		// syslog(LOG_INFO, "_backtrace : $entry_id: ".$entry['file'].".".$entry['line'].".".$entry['function']."()");
		// }
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$returnArr = array();
		if ($conf && $conf->bredea == 1) {
			try {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa");

				## Lecture de la réservation avec infos PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$resa = $this->getResaTable()->getResaWithPms($idResa);
				// var_dump($resa);die();

				if (!$resa) {
					## Pas de resa trouvée
					## ~~~~~~~~~~~~~~~~~~~
					return false;
				}
				$idApiPms	= $resa->idApiPms;
				$idPMS		= $resa->idPMS;
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa : idApiPms=$idApiPms idPMS=$idPMS");
				if (!$idPMS) {
					## Pas transmis au PMS
					## ~~~~~~~~~~~~~~~~~~~
					return false;
				}
				if (!$idApiPms) {
					$idApiPms	= 1;
				}
				if (!is_object($this->pms) || $idApiPms != $this->pms->getIdApiPms()) {
					## Connexion au PMS
					## ~~~~~~~~~~~~~~~~
					try {
						$this->pms	= null;
						$pmsGen	= new PmsGen($adapter, $idApiPms);
						if ($pmsGen) {
							$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
							if (is_object($pms)) {
								$this->pms	= $pms;
							}
						}
						if (!$this->pms) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms injoignable");
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
					}
				}
				if ($this->pms && is_object($this->pms)) {
					try {
						## Traitement en fonction du PMS
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						if ($this->pms->getClassName() === "Bredea") {
							return $this->getReservationBredea($resa);
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							return $this->pms->getReservationPms($resa);
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa Exception=".$ex->getMessage());
			}
		}
		return false;
	}

	public function getReservationBredea($resa)
	{
		$returnArr = array();
		try {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=".$resa->id);
			##$bredea = new BredeaSql();
			$bredea = $this->pms;

			$resa = $this->getResaTable()->getResa($resa->id);
			if (!$resa) {
				return false;
			}
			if ($resa->idPMS && !$resa->codeSite) {
				$resa->codeSite = $bredea->site;
			}
			if (!$resa->codeSite) {
				return false;
			}
			$numero = $flag = "";
			if ($resa->numDossier) {
				$numero = $resa->numDossier;
				$flag = "dossier";
			} elseif ($resa->numResa) {
				$numero = $resa->numResa;
				$flag = "resa";
			} elseif ($resa->idPMS) {
				$numero = $resa->idPMS;
				$flag = "demande";
			}
			if (!$flag || !$numero) {
				return false;
			}

			$locWL = $this->getLocatairesTable()->getLocataire($resa->idLocataire);

			$return = $bredea->lireReservation($numero, $resa->codeSite, $flag, $resa->typre);
			if (!empty($return)) {
				$locBredea = !empty($return['loc']) ? $return['loc'] : null;
				$resaBredea = !empty($return['resa']) ? $return['resa'] : null;
				$choix = !empty($return['choix']) ? $return['choix'] : null;
				$locExtra = !empty($return['locExtra']) ? $return['locExtra'] : null;
				$locSelect = !empty($return['locSelect']) ? $return['locSelect'] : null;
				$comments = !empty($return['comments']) ? $return['comments'] : null;

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idLocataire=".$resa->idLocataire." idResa=$idResa numero=$numero codeSite=".$resa->codeSite." flag=$flag locBredea=".json_encode($locBredea));
				if ($locBredea) {

					//cherche nationalite selon natADP
					if (trim($locBredea->idNationalite) != "") {
						$nat = $this->getTable('pays')->select(array('natADP' => $locBredea->idNationalite))->current();
						if ($nat) {
							$locBredea->idNationalite = $nat->id;
						} else {
							$locBredea->idNationalite = null;
						}
					}

					// on fusionne les infos Bredea avec celle de WL => resultat un array
					//il faut par la suite transformer l array on objet Locataires
					$result = $this->mergeData($locWL, $locBredea);
					$newLoc = new Locataires();
					$newLoc->exchangeArray($result);
					$returnArr['loc'] = $newLoc;//objet
					$returnArr['locArray'] = $result;//array
				}

				if ($resaBredea) {
					// on fusionne les infos Bredea avec celle de WL => resultat un array
					//il faut par la suite transformer l array on objet Resa
					$result = $this->mergeData($resa, $resaBredea);
					$result['pasDeFacture'] = $resaBredea->pasDeFacture;

					//on verifie si changement de logement (meme dossier) :
					//on affiche pas la date depart bredea pour l ancienne resa
					//on affiche pas la date arrivee bredea pour la nouvelle resa
					if ($resa->idNouvelleResa) {
						//on cherche la nouvelle resa pour verifie si les deux resa on le meme dossier
						$nr = $this->getResaTable()->getResa($resa->idNouvelleResa);
						if ($nr && $nr->numDossier == $resa->numDossier) {
							$result['dateDepart'] = $resa->dateDepart;
						}
					}
					if ($resa->idAncienneResa) {
						//on cherche l ancienne resa pour verifie si les deux resa on le meme dossier
						$nr = $this->getResaTable()->getResa($resa->idAncienneResa);
						if ($nr && $nr->numDossier == $resa->numDossier) {
							$result['dateArrivee'] = $resa->dateArrivee;
						}
					}

					$newResa = new Resa();
					$newResa->exchangeArray($result);
					$returnArr['resa'] = $newResa;
				}
			}
			$bredea->closeConnect();
			$this->pms	= null;
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
			echo $ex->getMessage();
		}
		return $returnArr;
	}

	//fusionner les deux objet ou array sans ecraser les valeurs de oldData avec newData sauf les null
	//return array
	public function mergeData($oldData, $newData)
	{
		//on les transforme en array
		if (!is_array($oldData)) {
			$oldData = get_object_vars($oldData);
		}
		if (!is_array($newData)) {
			$newData = get_object_vars($newData);
		}


		$data = array();
		//foreach ($oldData as $key => $value) {
		/*$value = trim($value);
		$value = iconv(mb_detect_encoding($value, mb_detect_order(), true), "UTF-8", $value);
		$data[$key] = $value;

		$newVal = !empty($newData[$key]) ? $newData[$key] : "";
		if($newVal && $newVal != "" && $newVal !="0"){
			$newVal = iconv(mb_detect_encoding($newVal, mb_detect_order(), true), "UTF-8", $newVal);
			$data[$key] = utf8_encode($newVal);
		}*/

		/*if(!$value || $value =="" || $value =="0"){
			if(!empty($oldData[$key])){
				if(trim($oldData[$key]) !="" && trim($oldData[$key]) !="0" ){
					$data[$key] = $oldData[$key];
				}
			}
		}*/
		//}
		foreach ($oldData as $key => $value) {
			$value = trim($value);
			$value = iconv(mb_detect_encoding($value, mb_detect_order(), true), "UTF-8", $value);
			$data[$key] = $value;

			$newVal = !empty($newData[$key]) ? $newData[$key] : "";
			$newVal = trim($newVal);
			$newVal = iconv(mb_detect_encoding($newVal, mb_detect_order(), true), "UTF-8", $newVal);
			if ($newVal && $newVal != "" && $newVal != "0") {
				$data[$key] = $newVal;
			}
		}
		//on parcours aussi newData, pour que les champs qui n existait pas dans oldData on les ajoute
		foreach ($newData as $key => $value) {
			$value = trim($value);
			$value = iconv(mb_detect_encoding($value, mb_detect_order(), true), "UTF-8", $value);
			if (empty($oldData[$key]) && empty($data[$key])) {
				$data[$key] = $value;
			}
		}
		return $data;
	}

	#######################FIN BREDEA##########################

	private function getTotalDureesIC()
	{
		$allEtat = $this->getAllEtatIC();
		$totalDuree = 0;
		foreach ($allEtat as $etat) {
			$totalDuree += $etat->duree;
		}
		return $totalDuree;
	}

	public function getTableObjet($table)
	{
		$table = new Tables($table, $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		return $table->getTable();
	}

	private function getTable($table)
	{
		$table = new Tables($table, $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
		return $table->getTable();
	}

	public function getActionsjsTable()
	{
		if (!$this->actionsjsTable) {
			$table = new Tables('actions_js', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$this->actionsjsTable = $table->getTable();
		}
		return $this->actionsjsTable;
	}

	public function getTraductionTable()
	{
		if (!$this->traductionTable) {
			$sm = $this->getServiceLocator();
			$this->traductionTable = $sm->get('Reservation\Model\TraductionTable');
		}
		return $this->traductionTable;
	}

	public function getEtatintercontratconfigTable()
	{
		if (!$this->etatICConfigTable) {
			$sm = $this->getServiceLocator();
			$this->etatICConfigTable = $sm->get('Reservation\Model\EtatintercontratconfigTable');
		}
		return $this->etatICConfigTable;
	}

	public function getRealEtatintercontratTable()
	{
		if (!$this->etatICTable) {
			$sm = $this->getServiceLocator();
			$this->etatICTable = $sm->get('Reservation\Model\EtatintercontratTable');
		}
		return $this->etatICTable;
	}

	public function getLangues()
	{
		$result = $this->getTableObjet('lang')->select(array('active' => '1'));
		$langues = array();
		foreach ($result as $row) {
			$langues[$row->codeISO] = $row->nom;
		}
		return $langues;
	}

	public function getDefaultLangue()
	{
		$row = $this->getTableObjet('lang')->select(array('default' => '1'))->current();
		return $row ? $row->codeLang : 'fr_FR';
	}

	private function getTypeChamp($idType)
	{
		$row = $this->getTableObjet('type_champs_formulaire')->select(array('id' => $idType))->current();
		if ($row) {
			return $row->type;
		}
		return false;
	}

	public function getChampsFormulaireTable()
	{
		return $this->getTableObjet('champs_formulaires');
	}

	public function getChampsTable()
	{
		if (!$this->champsTable) {
			$sm = $this->getServiceLocator();
			$this->champsTable = $sm->get('Reservation\Model\ChampsTable');
		}
		return $this->champsTable;
	}


	public function getChampdynamiqueTable()
	{
		if (!$this->champdynamiqueTable) {
			$sm = $this->getServiceLocator();
			$this->champdynamiqueTable = $sm->get('Reservation\Model\ChampdynamiqueTable');
		}
		return $this->champdynamiqueTable;
	}

	public function getValeurschampdynamiqueTable()
	{
		if (!$this->valeurschampdynamiqueTable) {
			$sm = $this->getServiceLocator();
			$this->valeurschampdynamiqueTable = $sm->get('Reservation\Model\ValeurschampdynamiqueTable');
		}
		return $this->valeurschampdynamiqueTable;
	}

	public function getLogementTable()
	{
		if (!$this->logementTable) {
			$sm = $this->getServiceLocator();
			$this->logementTable = $sm->get('Reservation\Model\LogementTable');
		}
		return $this->logementTable;
	}

	public function getEdlPrestationsTable()
	{
		if (!property_exists('EdlController', 'edlPrestationsTable')) {
			$sl = $this->getServiceLocator();
			$this->edlPrestationsTable = $sl->get('Reservation\Model\EdlPrestationsTable');
		}
		return $this->edlPrestationsTable;
	}

	public function getConfigurationTable()
	{
		if (!$this->configurationTable) {
			$sm = $this->getServiceLocator();
			$this->configurationTable = $sm->get('Reservation\Model\ConfigurationTable');
		}
		return $this->configurationTable;
	}

	public function getBatimentTable()
	{
		if (!$this->batimentTable) {
			$sm = $this->getServiceLocator();
			$this->batimentTable = $sm->get('Reservation\Model\BatimentTable');
		}
		return $this->batimentTable;
	}

	private function getConfig()
	{
		$table = $this->getTableObjet('configuration');
		$row = $table->select()->current();
		return $row;
	}

	public function getChoixTable()
	{
		if (!$this->choixTable) {
			$sm = $this->getServiceLocator();
			$this->choixTable = $sm->get('Reservation\Model\ChoixTable');
		}
		return $this->choixTable;
	}

	public function getDocumentTable()
	{
		if (!$this->documentTable) {
			$sm = $this->getServiceLocator();
			$this->documentTable = $sm->get('Reservation\Model\DocumentTable');
		}
		return $this->documentTable;
	}

	public function getLocatairesTable()
	{
		if (!$this->locatairesTable) {
			$sm = $this->getServiceLocator();
			$this->locatairesTable = $sm->get('Reservation\Model\LocatairesTable');
		}
		return $this->locatairesTable;
	}

	public function getLocataireTable()
	{
		if (!$this->locatairesTable) {
			$sm = $this->getServiceLocator();
			$this->locatairesTable = $sm->get('Reservation\Model\LocatairesTable');
		}
		return $this->locatairesTable;
	}

	public function getHistoriquemailTable()
	{
		if (!$this->historiquemailTable) {
			$sm = $this->getServiceLocator();
			$this->historiquemailTable = $sm->get('Reservation\Model\HistoriquemailTable');
		}
		return $this->historiquemailTable;
	}
	public function getHistoriquePushTable()
	{
		if (!$this->historiquePushTable) {
			$sm = $this->getServiceLocator();
			$this->historiquePushTable = $sm->get('Reservation\Model\HistoriquePushTable');
		}
		return $this->historiquePushTable;
	}
	public function getmodelesPushTable()
	{
		if (!$this->modelesPushTable) {
			$sm = $this->getServiceLocator();
			$this->modelesPushTable = $sm->get('Reservation\Model\ModelesPushTable');
		}
		return $this->modelesPushTable;
	}

	public function getResaTable()
	{
		if (!$this->reservationTable) {
			$sm = $this->getServiceLocator();
			$this->reservationTable = $sm->get('Reservation\Model\ResaTable');
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->reservationTable->setAdapter($adapter);
		}
		return $this->reservationTable;
	}

	public function getListesTable()
	{
		if (!$this->listesTable) {
			$sm = $this->getServiceLocator();
			$this->listesTable = $sm->get('Reservation\Model\ListesTable');
		}
		return $this->listesTable;
	}

	public function getBoutiqueListesTable()
	{
		$table = $this->getTableObjet('boutique_listes');
		return $table;
	}

	public function getLogsTable()
	{
		if (!$this->logsTable) {
			$sm = $this->getServiceLocator();
			$this->logsTable = $sm->get('Reservation\Model\LogsTable');
		}
		return $this->logsTable;
	}

	public function getPaysTable()
	{
		if (!$this->paysTable) {
			$sm = $this->getServiceLocator();
			$this->paysTable = $sm->get('Application\Model\PaysTable');
		}
		return $this->paysTable;
	}

	public function getProgrammeTable()
	{
		if (!$this->programmeTable) {
			$sm = $this->getServiceLocator();
			$this->programmeTable = $sm->get('Reservation\Model\ProgrammeTable');
		}
		return $this->programmeTable;
	}

	public function getPileTable()
	{
		if (!$this->pileTable) {
			$sm = $this->getServiceLocator();
			$this->pileTable = $sm->get('Application\Model\PileTable');
		}
		return $this->pileTable;
	}

	public function getComptesTable()
	{
		if (!$this->compteTable) {
			$sm = $this->getServiceLocator();
			$this->compteTable = $sm->get('Etudiant\Model\ComptesTable');
		}
		return $this->compteTable;
	}

	public function getTypelogementTable()
	{
		if (!$this->typelogementTable) {
			$sm = $this->getServiceLocator();
			$this->typelogementTable = $sm->get('Reservation\Model\TypelogementTable');
		}
		return $this->typelogementTable;
	}

	public function getModelesmailTable()
	{
		if (!$this->modelesmailTable) {
			$sm = $this->getServiceLocator();
			$this->modelesmailTable = $sm->get('Reservation\Model\ModelesmailTable');
		}
		return $this->modelesmailTable;
	}

	public function getTypemailTable()
	{
		if (!$this->typemailTable) {
			$sm = $this->getServiceLocator();
			$this->typemailTable = $sm->get('Reservation\Model\TypemailTable');
		}
		return $this->typemailTable;
	}

	public function getModelescampagneTable()
	{
		if (!$this->modelescampagneTable) {
			$sm = $this->getServiceLocator();
			$this->modelescampagneTable = $sm->get('Reservation\Model\ModelescampagneTable');
		}
		return $this->modelescampagneTable;
	}

	public function getChampsFormTable()
	{
		if (!$this->champsFormTable) {
			$table = new Tables('champs_formulaires', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$this->champsFormTable = $table->getTable();
		}
		return $this->champsFormTable;
	}

	public function getDocumentLocataireTable()
	{
		if (!$this->documentLocataireTable) {
			$table = new Tables('document_locataire', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$this->documentLocataireTable = $table->getTable();
		}
		return $this->documentLocataireTable;
	}
	public function getFormulaireTableModel()
	{
		if (!$this->formulaireTableModel) {
			$sm = $this->getServiceLocator();
			$this->formulaireTableModel = $sm->get('Reservation\Model\FormulaireTable');
		}
		return $this->formulaireTableModel;
	}

	public function getResidencesTable()
	{
		if (!$this->residencesTable) {
			$sm = $this->getServiceLocator();
			$this->residencesTable = $sm->get('Reservation\Model\ResidencesTable');
		}
		return $this->residencesTable;
	}

	public function getLocatairesAccesResaTable()
	{
		if (!$this->locatairesAccesResaTable) {
			$sm = $this->getServiceLocator();
			$this->locatairesAccesResaTable = $sm->get('Reservation\Model\LocatairesAccesResaTable');
		}
		return $this->locatairesAccesResaTable;
	}

	public function getEdlModeleTable()
	{
		if (!property_exists('EdlController', 'edlModeleTable')) {
			$sl = $this->getServiceLocator();
			$this->edlModeleTable = $sl->get('Reservation\Model\EdlModeleTable');
		}
		return $this->edlModeleTable;
	}



	public function getEdlCatTable()
	{
		if (!property_exists('EdlController', 'edlCatTable')) {
			$sl = $this->getServiceLocator();
			$this->edlCatTable = $sl->get('Reservation\Model\EdlCatTable');
		}
		return $this->edlCatTable;
	}

	public function getEdlSousCatTable()
	{
		if (!property_exists('EdlController', 'edlSousCatTable')) {
			$sl = $this->getServiceLocator();
			$this->edlSousCatTable = $sl->get('Reservation\Model\EdlSousCatTable');
		}
		return $this->edlSousCatTable;
	}

	public function getEdlArticleTable()
	{
		if (!property_exists('EdlController', 'edlArticleTable')) {
			$sl = $this->getServiceLocator();
			$this->edlArticleTable = $sl->get('Reservation\Model\EdlArticleTable');
		}
		return $this->edlArticleTable;
	}

	public function getEdlParametresTable()
	{
		if (!property_exists('EdlController', 'edlParametresTable')) {
			$sl = $this->getServiceLocator();
			$this->edlParametresTable = $sl->get('Reservation\Model\EdlParametresTable');
		}
		return $this->edlParametresTable;
	}

	public function getDemandesTable()
	{
		if (!$this->demandesTable) {
			$sm = $this->getServiceLocator();
			$this->demandesTable = $sm->get('Reservation\Model\DemandesTable');
		}
		return $this->demandesTable;
	}

	public function getUserTable()
	{
		if (!$this->userTable) {
			$sm = $this->getServiceLocator();
			$this->userTable = $sm->get('Reservation\Model\UserTable');
		}
		return $this->userTable;
	}

	public function getColisTable()
	{
		if (!$this->colisTable) {
			$sm = $this->getServiceLocator();
			$this->colisTable = $sm->get('Reservation\Model\ColisTable');
		}
		return $this->colisTable;
	}

	public function getEdlTable()
	{
		if (!property_exists('EdlController', 'edlTable')) {
			$sl = $this->getServiceLocator();
			$this->edlTable = $sl->get('Reservation\Model\EdlTable');
		}
		return $this->edlTable;
	}

	// model pour la fonction server side
	public function getTableIntercontratServerSide()
	{
		$tableIC = new IntercontratTable();
		return $tableIC;
	}


	public function getDemandesModelesTable()
	{
		if (!$this->demandesModelesTable) {
			$sm = $this->getServiceLocator();
			$this->demandesModelesTable = $sm->get('Reservation\Model\DemandesModelesTable');
		}
		return $this->demandesModelesTable;
	}

	public function getRdvRenonceTable()
	{
		if (!$this->rdvRenonceTable) {
			$sm = $this->getServiceLocator();
			$this->rdvRenonceTable = $sm->get('Reservation\Model\RdvRenonceTable');
		}
		return $this->rdvRenonceTable;
	}

	public function getRdvTable()
	{
		if (!$this->rdvTable) {
			$sm = $this->getServiceLocator();
			$this->rdvTable = $sm->get('Reservation\Model\RdvTable');
		}
		return $this->rdvTable;
	}

	public function getfields($str)
	{
		preg_match_all('/\%([A-Za-z0-9\-_]+?)\%/', $str, $matches);
		return $matches[1];
	}

	public function removeAccent($str, $charset = 'utf-8')
	{
		$str = htmlentities($str, ENT_NOQUOTES, $charset);

		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
		$str = preg_replace('/\s/', '_', $str);//supprimer les espaces
		$str = preg_replace('/\//', '', $str);//supprimer les espaces
		$str = preg_replace('#(.\')#', '', $str);

		return strtolower($str);
	}

	public function gencafAction()
	{
		$result = '';
		if (isset($_FILES['csvFile']['tmp_name'])) {
			$row = 1;
			$i = 1;
			// ENREGISTREMENT EMETTEUR
			$en_emetteur = array(
				array('lg' => 2, 'type' => 'N', 'def' => 3),
				array('lg' => 2, 'type' => 'N', 'def' => 42),
				array('lg' => 6, 'type' => 'AN'),
				array('lg' => 5, 'type' => 'AN'),
				array('lg' => 3, 'type' => 'AN', 'def' => ''),
				array('lg' => 6, 'type' => 'N', 'def' => 120617),
				array('lg' => 24, 'type' => 'AN', 'def' => 'CAISSE ALLOCATIONS FAMIL'),
				array('lg' => 24, 'type' => 'AN', 'def' => 'ALEGESSEC'),
				array('lg' => 9, 'type' => 'AN', 'def' => ''),
				array('lg' => 5, 'type' => 'AN', 'def' => '30003'),
				array('lg' => 5, 'type' => 'AN', 'def' => '01658'),
				array('lg' => 11, 'type' => 'AN', 'def' => '00037275738'),
				array('lg' => 1, 'type' => 'AN', 'def' => '6'),
				array('lg' => 30, 'type' => 'AN', 'def' => ' MUTATION LOGEMENT MAJ IDENTIF'),
				array('lg' => 27, 'type' => 'AN', 'def' => ' '),
			);

			// ENREGISTREMENT DETAIL
			$en_detail = array(
				array('lg' => 2, 'type' => 'N', 'def' => 6),
				array('lg' => 2, 'type' => 'N', 'def' => 42),
				array('lg' => 6, 'type' => 'AN'),
				array('lg' => 5, 'type' => 'AN'),
				array('lg' => 3, 'type' => 'AN', 'def' => ''),
				array('lg' => 5, 'type' => 'AN', 'def' => ''),
				array('lg' => 13, 'type' => 'AN', 'def' => '00000000L1007'),
				array('lg' => 14, 'type' => 'AN'),
				array('lg' => 20, 'type' => 'AN'),
				array('lg' => 13, 'type' => 'AN'),
				array('lg' => 2, 'type' => 'N', 'def' => 01),
				array('lg' => 25, 'type' => 'AN', 'def' => '                         '),
				array('lg' => 6, 'type' => 'N'),
				array('lg' => 6, 'type' => 'N'),
				array('lg' => 38, 'type' => 'AN', 'def' => ''),
			);

			// ENREGISTREMENT TOTAL
			$en_total = array(
				array('lg' => 2, 'type' => 'N', 'def' => 8),
				array('lg' => 2, 'type' => 'N', 'def' => 42),
				array('lg' => 6, 'type' => 'AN'),
				array('lg' => 5, 'type' => 'AN'),
				array('lg' => 3, 'type' => 'AN', 'def' => ''),
				array('lg' => 67, 'type' => 'AN', 'def' => ''),
				array('lg' => 6, 'type' => 'N', 'def' => '000001'),
				array('lg' => 69, 'type' => 'AN', 'def' => '                                                                     '),
			);

			// RAPPEL : NUM_NAT_EM = 0:2 - CODE_BAI = 1:3 - NOM = 2:8 - PRENOM = 3:9 - NUM_ALLOC = 4:7 - DATE_DEP = 5:12

			if (($handle = fopen($_FILES['csvFile']['tmp_name'], "r")) !== false) {
				while (($data = fgetcsv($handle, 205, ";")) !== false) {
					if ($row == 1 && isset($_POST['hasHeader'])) {
						$row++;
						continue;
					}

					// STORE INFO
					if ($i == 1) {
						$info = $data;
						foreach ($en_emetteur as $key => $row) {
							if (array_key_exists('def', $row)) {
								if ($row['type'] == 'N') {
									$result .= str_pad($row['def'], $row['lg'], 0, STR_PAD_LEFT);
								} else {
									$result .= str_pad($row['def'], $row['lg']);
								}
							} else {
								if ($key == 2) {
									$result .= str_pad($info[0], $row['lg'], 0, STR_PAD_LEFT);
								} elseif ($key == 3) {
									$result .= str_pad($info[1], $row['lg'], 0, STR_PAD_LEFT);
								}
							}
						}
						$result .= PHP_EOL;
					}

					$working_array = array_fill(0, 15, null);

					// FIELDS COUNT
					$num = count($data);

					foreach ($en_detail as $key => $row) {
						if (array_key_exists('def', $row)) {
							if ($row['type'] == 'N') {
								$result .= str_pad($row['def'], $row['lg'], 0, STR_PAD_LEFT);
							} else {
								$result .= str_pad($row['def'], $row['lg']);
							}
						} else {
							// NUM_NAT_EM
							if ($key == 2) {
								$result .= str_pad($data[0], $row['lg'], 0, STR_PAD_LEFT);
							}
							// CODE_BAI
							elseif ($key == 3) {
								$result .= str_pad($data[1], $row['lg'], 0, STR_PAD_LEFT);
							}
							// NUM_ALLOC
							elseif ($key == 7) {
								$result .= str_pad($data[4], $row['lg'], 0, STR_PAD_LEFT);
							}
							// NOM
							elseif ($key == 8) {
								$result .= str_pad($data[2], $row['lg']);
							}
							// PRENOM
							elseif ($key == 9) {
								$result .= str_pad($data[3], $row['lg']);
							}
							// DATE_DEP
							elseif ($key == 11) {
								$result .= str_replace('/', '', $data[5]);
							}
							// DATE_DEP
							elseif ($key == 12) {
								$result .= str_replace('/', '', $data[5]);
							}
						}
					}
					$result .= PHP_EOL;
					$i++;
				}
				fclose($handle);

				foreach ($en_total as $key => $row) {
					if (array_key_exists('def', $row)) {
						if ($row['type'] == 'N') {
							$result .= str_pad($row['def'], $row['lg'], 0, STR_PAD_LEFT);
						} else {
							$result .= str_pad($row['def'], $row['lg']);
						}
					} else {
						if ($key == 2) {
							$result .= str_pad($info[0], $row['lg'], 0, STR_PAD_LEFT);
						} elseif ($key == 3) {
							$result .= str_pad($info[1], $row['lg'], 0, STR_PAD_LEFT);
						}
					}
				}
			}
		}
		// FILE POINTER
		$filename = 'caf_'.uniqid().'.txt';
		$output = getcwd().'/public/docs/caf/'.$filename;
		$download_url = '/docs/caf/'.$filename;
		file_put_contents($output, $result);

		// DOWNLOAD
		echo $download_url;
		exit;
	}

	private function endsWith($haystack, $needle)
	{
		$length = strlen($needle);
		return substr($haystack, -$length) === $needle;
	}

	public function gencafbredeatestAction()
	{
		if (!is_dir(getcwd()."/public/data/export/CAFDepart")) {
			mkdir(getcwd()."/public/data/export/CAFDepart", 755, true);
		}
		//$bredea = new BredeaSql();
		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
		// OUYANG / KANNAN / BOUO BELLA / GOTETI
		$resaIds = array(176, 236, 222, 1067);
		// GET ALL RESA WITH ETAT = 6 AND GROUP THEM BY SITE
		$reservations = $this->getResaTable()->getResaGroupSiteTest();

		// LOOP THEM
		foreach ($reservations as $site => $rows) {
			$result = [];
			// GET SITE
			$siteRow = $bredea->getSitesBySiteCode(str_pad($site, 2, 0, STR_PAD_LEFT));

			// CREATE EMETTEUR
			$result[] = '0342900'.$siteRow['si_emetteur'].$siteRow['csi_bailleur'].'   '.date('ymd').'CAISSE ALLOCATIONS FAMILALEGESSEC                        3000301658000372757386MUTATION LOGEMENT MAJ IDENTIF                            ';

			// LOOP TO CREATE DETAILS
			foreach ($rows as $row) {
				$this->getResaTable()->updateResa(array('cafTreated' => 1), array('id' => $row->id));
				$dossier = $bredea->getDossiByResa($row);
				if ($dossier['dossi_prenom'] == null) {
					continue;
				}

				$result[] = '0642900' . $siteRow['si_emetteur'] . $siteRow['csi_bailleur'] . '        ' . str_pad($row->codeCAF, 13, ' ', STR_PAD_LEFT) . $dossier['dossi_noalloc'] . $dossier['dossi_nomcaf'] . $dossier['dossi_prenom'] . '01                         ' . $dossier['dossi_finbail'] . $dossier['dossi_finbail'] . str_pad('', 38, ' ', STR_PAD_LEFT);
			}

			// CREATE TOTAL
			$result[] = '0842900' . $siteRow['si_emetteur'] . $siteRow['csi_bailleur'] . '   ' . str_pad('', 67, ' ', STR_PAD_LEFT) .'000006' . str_pad('', 69, ' ', STR_PAD_LEFT);

			// FILE POINTER
			$outputString = implode(PHP_EOL, $result);
			$filename = 'caf_'.$siteRow['si_emetteur'].'_'.$siteRow['csi_bailleur'].'_'.uniqid().'.txt';
			$output = getcwd().'/public/data/export/CAFDepart/'.$filename;
			$download_url = '/data/export/CAFDepart/'.$filename;
			file_put_contents($output, $outputString);
		}

		exit;
	}
	public function displaycafAction()
	{
		$result = array();
		$bredea		= null;
		$tools = new Tools();

		## Recherche de la présence du PMS-Bredea car sa présence implique un fonctionnement particulier
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$apis	= $this->getApipmsTable()->getAllActiveApiByClass();
		if ($apis["Bredea"]) {
			## Init de la version
			$idApiPms	= reset($apis["Bredea"]);
			$this->initPMS($idApiPms);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiPms=$idApiPms avec Bredea");
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : FILES=".json_encode($_FILES));

		if (isset($_FILES['cafFile']['tmp_name'])) {
			$rows = array();
			$i = 0;
			if (($handle = fopen($_FILES['cafFile']['tmp_name'], "r")) !== false) {
				while (($data = fgets($handle, 205)) !== false) {
					// GET RECORD TYPE
					$type = substr($data, 0, 2);
					// IF START WITH 06
					if ($type == 06) {
						$rows[$i]['code'] = $tools->removeAccentOnly(substr($data, 23, 13));
						## On ne prend en compte que les 8 derniers caractéres du numéro d'allocataire
						$rows[$i]['num'] = substr(substr($data, 36, 15), -8);
						$rows[$i]['nom'] = substr($data, 51, 20);
						$rows[$i]['prenom'] = substr($data, 71, 12);
						$rows[$i]['typeAide'] = substr($data, 4, 6);//positions 5 à 7 = « 900 » si APL , « 999 » si AL + code CAF ou code MSA sur 3 caractères
						$rows[$i]['periode'] = substr($data, 83, 8);
						$rows[$i]['montantAideNet'] = substr($data, 91, 11);
						$rows[$i]['montantRetenue'] = substr($data, 102, 11);
						$i++;
					}
				}
				## optimisation : on cherche tout les dossier pour ne pas introduire des rquetes dans la boucle
				$dossiersPMS = array();
				$dossiersWL = array();
				if ($bredea) {
					$dRows = $bredea->getRow('001fdossi');
					foreach($dRows as $d){
						$key1 = trim($d['dossi_apl']).'_'.trim($d['dossi_noalloc']);
						$key2 = trim($d['dossi_site']).'_'.trim($d['dossi_nodoss']);
						$dossiersPMS['par_apl_noalloc'][$key1] = $d;
						$dossiersPMS['par_site_nodoss'][$key2] = $d;

					}
					$locNotAssigned = $this->encodeEnUtf8($bredea->getRows('001fdossi', array('dossi_noalloc' => null, 'dossi_trait' => 'A'), '', '', array('champ' => 'dossi_nom,dossi_debbail')));
				} else {
					$locNotAssigned = array();
					$resas = $this->getResaTable()->getResaBy(array(), $avecGroup = false, $avecLocataire = true, $order = array('locataires.nom', 'locataires.prenom'));
					if ($resas) {
						foreach ($resas as $resa) {
							$locNotAssigned1			= array();
							$locNotAssigned1['dossi_nom']		= $resa->nomLocataire;
							$locNotAssigned1['dossi_prenom']	= $resa->prenomLocataire ?: '';
							$locNotAssigned1['dossi_site']		= '';
							$locNotAssigned1['dossi_nodoss']	= '';
							$locNotAssigned1['idLocataire']		= $resa->idLocataire;
							$locNotAssigned1['dossi_noalloc']	= $resa->cafNum;

							$locNotAssigned[]			= $locNotAssigned1;

							if($resa->cafNum) $dossiersWL['par_cafNum'][trim($resa->cafNum)] = $resa;
						}
					}
				}

				// GET RESULT OF ALL LOCATAIRES
				foreach ($rows as $row) {
					$result[$row['num']]['cafCode']		= $row['code'];
					$result[$row['num']]['cafNom'] 		= explode('-', $row['nom'])[0];
					$result[$row['num']]['cafPrenom'] 	= explode('-', $row['prenom'])[0];

					$locataires = array();
					$i = 1;
					$numeroAllocataire	= $row['num'];
					$numeroLocataire	= $row['code'];
					$nom = trim($row['nom']);
					$prenom = trim($row['prenom']);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nom=$nom prenom=$prenom : numeroAllocataire=$numeroAllocataire numeroLocataire=$numeroLocataire");

					/** On recherche par numéro allocataire en premier lieu **/
					if ($bredea) {
						$locataireNumAlloc = $bredea->getRow('001fdossi', array('dossi_apl' => 'O', 'dossi_noalloc' => $row['num']));
					} else {
						## Recherche du numéro d'allocataire dans la table réservations
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$locataireNumAlloc = array();
						$resas = $this->getResaTable()->getResaBy(array('cafNum' => $numeroAllocataire), $avecGroup = false, $avecLocataire = true);
						if ($resas && $resas->count() > 0) {
							$resa	= $resas->current();
							##syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : resa=".json_encode($resa));
							$locataireNumAlloc['dossi_nom']		= $resa->nomLocataire;
							$locataireNumAlloc['dossi_prenom']	= $resa->prenomLocataire;
						}
					}

					/** Si on trouve on cherche par nom et prenom trouvé pour vérifier si plusieurs dossiers**/
					if (!empty($locataireNumAlloc)) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : locataireNumAlloc=".json_encode($locataireNumAlloc));
						$locs = array();
						$dossi_nom	= $locataireNumAlloc['dossi_nom'];
						$dossi_prenom	= $locataireNumAlloc['dossi_prenom'];
						if ($bredea) {
							$dossi_nom	= utf8_encode(trim($dossi_nom));
							$dossi_prenom	= utf8_encode(trim($dossi_prenom));
						}
						$locs = $this->getLocatairesTable()->getLocaByNameAndSurname($dossi_nom, $dossi_prenom);
						$locataireNumAllocM = array();
						if ($locs) {
							foreach ($locs as $loc) {
								$locataireNumAllocM[] = $loc;
							}
						}
						$nbLocsNumAllocM = count($locataireNumAllocM);
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nbLocsNumAllocM=$nbLocsNumAllocM");
						if ($nbLocsNumAllocM == 1) {
							/** Si on a une seule réponse **/
							$result[$row['num']]['multiple']		= false;
							$result[$row['num']]['exists'] 			= true;
							$result[$row['num']]['idLocataire'] 		= $locataireNumAllocM[0]->id;
							$result[$row['num']]['idResa']	 		= $locataireNumAllocM[0]->idReservation;
							$result[$row['num']]['dossi_nodoss'] 		= $locataireNumAllocM[0]->numDossier;
							$result[$row['num']]['dossi_site'] 		= $locataireNumAllocM[0]->codeSite;
							$result[$row['num']]['dossi_nom'] 		= $locataireNumAllocM[0]->nom;
							$result[$row['num']]['dossi_prenom'] 		= $locataireNumAllocM[0]->prenom;
							$result[$row['num']]['dossi_adr1'] 		= $locataireNumAllocM[0]->adresse ?: '';
							$result[$row['num']]['dossi_cp'] 		= $locataireNumAllocM[0]->codePostal;
							$result[$row['num']]['dossi_ville'] 		= $locataireNumAllocM[0]->ville;
							if ($bredea) {
								$result[$row['num']]['dossi_debbail'] 		= date("d-m-Y", strtotime($locataireNumAllocM[0]->dateArriveeTheorique));
								$result[$row['num']]['dossi_finbail'] 		= date("d-m-Y", strtotime($locataireNumAllocM[0]->dateDepartTheorique));
							} else {
								$result[$row['num']]['dossi_debbail'] 		= ($locataireNumAllocM[0]->dateArrivee && $locataireNumAllocM[0]->dateArrivee != "0000-00-00") ?
															date("d-m-Y", strtotime($locataireNumAllocM[0]->dateArrivee)) : '';
								$result[$row['num']]['dossi_finbail'] 		= ($locataireNumAllocM[0]->dateDepart && $locataireNumAllocM[0]->dateDepart != "0000-00-00") ?
															date("d-m-Y", strtotime($locataireNumAllocM[0]->dateDepart)) : '';
							}
							$result[$row['num']]['archived'] 		= $locataireNumAllocM[0]->archive == '1' ? 'Oui' : 'Non';
							$result[$row['num']]['numeroChambre'] 		= $locataireNumAllocM[0]->numeroChambre ?: '';
							$result[$row['num']]['dossi_noalloc'] 		= $locataireNumAllocM[0]->cafNum;
						} else {
							/** Si on a plusieurs dossiers on les affiches tous **/
							$result[$row['num']]['multiple']	= true;
							$result[$row['num']]['exists'] 		= true;
							$nbNumCaf = 0;
							foreach ($locataireNumAllocM as $locsNumAllocM) {
								/** On compte le nombre de numéro allocataire présent dans les enregistrement sauf le dernier **/
								if (!empty($locsNumAllocM->cafNum) && $i != $nbLocsNumAllocM) {
									$nbNumCaf++;
								}
								$result[$row['num']]['loc'][$i]['idLocataire']		= $locsNumAllocM->idLocataire;
								$result[$row['num']]['loc'][$i]['idResa']	 	= $locsNumAllocM->idReservation;
								$result[$row['num']]['loc'][$i]['dossi_nodoss'] 	= $locsNumAllocM->numDossier;
								$result[$row['num']]['loc'][$i]['dossi_site'] 		= $locsNumAllocM->codeSite;
								$result[$row['num']]['loc'][$i]['dossi_nom'] 		= $locsNumAllocM->nom;
								$result[$row['num']]['loc'][$i]['dossi_prenom'] 	= $locsNumAllocM->prenom;
								$result[$row['num']]['loc'][$i]['dossi_adr1'] 		= $locsNumAllocM->adresse ?: '';
								$result[$row['num']]['loc'][$i]['dossi_cp'] 		= $locsNumAllocM->codePostal;
								$result[$row['num']]['loc'][$i]['dossi_ville'] 		= $locsNumAllocM->ville;
								if ($bredea) {
									$result[$row['num']]['loc'][$i]['dossi_debbail'] 	= date("d-m-Y", strtotime($locsNumAllocM->dateArriveeTheorique));
									$result[$row['num']]['loc'][$i]['dossi_finbail'] 	= date("d-m-Y", strtotime($locsNumAllocM->dateDepartTheorique));
								} else {
									$result[$row['num']]['loc'][$i]['dossi_debbail'] 	= ($locsNumAllocM->dateArrivee && $locsNumAllocM->dateArrivee != "0000-00-00") ?
																	date("d-m-Y", strtotime($locsNumAllocM->dateArrivee)) : '';
									$result[$row['num']]['loc'][$i]['dossi_finbail'] 	= ($locsNumAllocM->dateDepart && $locsNumAllocM->dateDepart != "0000-00-00") ?
																	date("d-m-Y", strtotime($locsNumAllocM->dateDepart)) : '';
								}
								$result[$row['num']]['loc'][$i]['archived'] 		= $locsNumAllocM->archive == '1' ? 'Oui' : 'Non';
								$result[$row['num']]['loc'][$i]['numeroChambre'] 	= $locsNumAllocM->numeroChambre ?: '';
								$result[$row['num']]['loc'][$i]['dossi_noalloc'] 	= $locsNumAllocM->cafNum;
								$i++;
							}
							/** Si on a un seul numéro allocataire dans la derniere réservation **/
							$result[$row['num']]['oneCafNum'] 		= false;
							if ($nbNumCaf == 0 && !empty($result[$row['num']]['loc'][$nbLocsNumAllocM]['dossi_noalloc'])) {
								$result[$row['num']]['oneCafNum'] 		= true;
							}
						}
						/** Non trouve par numero allocataire => on cherche par nom et prenom **/
					} else {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nom=$nom prenom=$prenom : no-numeroAllocataire");
						$locs = $this->getLocatairesTable()->getLocaByNameAndSurname($nom, $prenom);

						/** Trouve par nom et prenom => on affiche toute les lignes correspondantes **/
						if ($locs && $locs->count()) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nom=$nom prenom=$prenom  : no-numeroAllocataire nb_locataires=".$locs->count());
							$result[$row['num']]['multiple']	= true;
							$result[$row['num']]['exists'] 		= true;
							foreach ($locs as $locataire) {
								///** Non trouve par numero allocataitre => on cherche par nom et prenom **/
								$locataireB = array();
								$locataireB = $bredea ? $bredea->getRow('001fdossi', array('dossi_site' => $locataire->codeSite, 'dossi_nodoss' => $locataire->numDossier)) : array();
								$result[$row['num']]['loc'][$i]['idLocataire']	 	= $locataire->id;
								$result[$row['num']]['loc'][$i]['idResa']	 	= $locataire->idReservation;
								$result[$row['num']]['loc'][$i]['dossi_nodoss'] 	= $locataire->numDossier;
								$result[$row['num']]['loc'][$i]['dossi_site'] 		= $locataire->codeSite;
								$result[$row['num']]['loc'][$i]['dossi_nom'] 		= $locataire->nom;
								$result[$row['num']]['loc'][$i]['dossi_prenom'] 	= $locataire->prenom;
								$result[$row['num']]['loc'][$i]['dossi_adr1'] 		= $locataire->adresse ?: '';
								$result[$row['num']]['loc'][$i]['dossi_cp'] 		= $locataire->codePostal;
								$result[$row['num']]['loc'][$i]['dossi_ville'] 		= $locataire->ville;
								if ($bredea) {
									$result[$row['num']]['loc'][$i]['dossi_debbail'] 	= date("d-m-Y", strtotime($locataireB['dossi_debbail']));
									$result[$row['num']]['loc'][$i]['dossi_finbail'] 	= date("d-m-Y", strtotime($locataireB['dossi_finbail']));
									$result[$row['num']]['loc'][$i]['dossi_noalloc'] 	= trim($locataireB['dossi_noalloc']);
								} else {
									$result[$row['num']]['loc'][$i]['dossi_debbail'] 	= ($locataire->dateArrivee && $locataire->dateArrivee != "0000-00-00") ?
																	date("d-m-Y", strtotime($locataire->dateArrivee)) : '';
									$result[$row['num']]['loc'][$i]['dossi_finbail'] 	= ($locataire->dateDepart && $locataire->dateDepart != "0000-00-00") ?
																	date("d-m-Y", strtotime($locataire->dateDepart)) : '';
									$result[$row['num']]['loc'][$i]['dossi_noalloc'] 	= $locataire->cafNum;
								}
								$result[$row['num']]['loc'][$i]['archived'] 		= $locataire->archive == '1' ? 'Oui' : 'Non';
								$result[$row['num']]['loc'][$i]['numeroChambre'] 	= $locataire->numeroChambre ?: '';
								$i++;
							}
						} else {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nom=$nom prenom=$prenom : no-numeroAllocataire  no-locataires");
							$result[$row['num']]['multiple']	= false;
							$result[$row['num']]['exists'] 		= false;
						}
					}
				}
			}
		}
		$view = new JsonModel(array(
					'success' => true,
					'data' => $result,
					'locNotAssigned' => $locNotAssigned,
			));
		$view->setTerminal(true);
		return $view;
	}

	public function updateCafAction()
	{
		$result = array();
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$bredea		= null;

			## Recherche de la présence du PMS-Bredea car sa présence implique un fonctionnement particulier
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$apis	= $this->getApipmsTable()->getAllActiveApiByClass();
			if ($apis["Bredea"]) {
				## Init de la version
				$idApiPms	= reset($apis["Bredea"]);
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiPms=$idApiPms avec Bredea");
			}
			$data = $request->getPost('data');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keys_data=".json_encode(array_keys($data)));

			if ($data) {
				foreach ($data as $cafNum => $value) {
					if ($value != '') {
						try {
							list($idResa, $idLocataire, $dossi_site, $dossi_nodoss, $dossi_nom, $dossi_nomB, $dossi_prenom, $cafCode) = explode('|', $value);
							/** On recherche par nom et prénom si il existe plusieurs dossiers => Si oui alors on efface le noalloc de l'ancien dossier **/

							if ($idLocataire && $idResa && $cafNum && $cafCode) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire cafNum=$cafNum cafCode=$cafCode");
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idLocataire, idResa, cafNum ou cafCode vides : abandon value=$value");
								continue;
							}
							if ($bredea) {
								$dossi_nomB	= utf8_encode(trim($dossi_nomB));
								$dossi_prenom	= utf8_encode(trim($dossi_prenom));
							}
							$locataires = $this->getLocatairesTable()->getLocaByNameAndSurname($dossi_nomB, $dossi_prenom);
							foreach ($locataires as $loc) {
								##syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire loc=".json_encode($loc));
								if ($bredea) {
									if ($loc->numDossier == $dossi_nodoss && $loc->codeSite == $dossi_site) {
										// BREDEA
										$setDossi = array(
											'dossi_apl'		=> 'O',
											'dossi_noalloc'	=> str_pad($cafNum, 15),
											'dossi_nomcaf'	=> str_pad(strtoupper($dossi_nom), 20),
										);
										// WL
										$setValue = array(
											'cafNum' => $cafNum,
											'cafCode' => $cafCode,
										);
									} else {
										// BREDEA
										$setDossi = array(
											'dossi_apl'		=> 'N',
											'dossi_noalloc'	=> "",
											'dossi_nomcaf'	=> "",
										);
										// WL
										$setValue = array(
											'cafNum' => "",
										);
									}
									// MISE A JOUR BREDEA
									$whereDossi = array(
										'dossi_site'	=> $loc->codeSite,
										'dossi_nodoss'	=> $loc->numDossier,
									);
									$result[] = $bredea->updateRow('001fdossi', $setDossi, $whereDossi);

									// MISE A JOUR WL
									$whereValue = array(
										'numDossier'	=> $loc->numDossier,
										'codeSite'	=> $loc->codeSite,
									);
									$this->getResaTable()->updateResa($setValue, $whereValue);
								} else {
									## Cas de CeriFoyer
									## ~~~~~~~~~~~~~~~~
									$setValue	= array();
									if ($loc->cafNum == $cafNum) {
										## Pas besoin de le réécrire
										## ~~~~~~~~~~~~~~~~~~~~~~~~~
									} elseif (!$loc->cafNum) {
										## On peut l'écrire
										## ~~~~~~~~~~~~~~~~
										$setValue['cafNum']	= $cafNum;
									} elseif (strpos($cafNum, $loc->cafNum) !== false) {
										## Différent mais le numéro mémorisé est un sous-ensemble du bon numéro
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										$setValue['cafNum']	= $cafNum;
									} else {
										## Si vraiment différents, ne pas les écrire : abandon
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire cafNum=".$loc->cafNum." différent : abandon");
										continue;
									}
									if ($loc->cafCode == $cafCode) {
										## Pas besoin de le réécrire
										## ~~~~~~~~~~~~~~~~~~~~~~~~~
									} elseif (!$loc->cafCode) {
										## On peut l'écrire
										## ~~~~~~~~~~~~~~~~
										$setValue['cafCode']	= $cafCode;
									} else {
										## Si différent, ne pas les écrire : abandon
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire cafCode=".$loc->cafCode." différent : abandon");
										continue;
									}
									if ($setValue) {
										## Il y a une modification à écrire
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										$whereValue	= array('idLocataire' => $idLocataire);
										$this->getResaTable()->updateResa($setValue, $whereValue);

										$locataire = $this->getLocatairesTable()->getLocataire($idLocataire);

										if ($locataire && ($idApiPms = $locataire->idLocataireApiPms)) {
											## Ecriture dans le PMS
											## ~~~~~~~~~~~~~~~~~~~~
											if (!$this->pms || $idApiPms != $this->pms->getIdApiPms()) {
												$this->initPMS($idApiPms);
											}
											$this->pms->updateNumerosCaf($locataire, $setValue);
										}
									} else {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLocataire=$idLocataire cafNum=$cafNum cafCode=$cafCode : inchange");
									}
								}
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ERROR-exception=".$ex->getMessage());
						}
					}
				}
			}
		}
		$view = new JsonModel(array(
			'success' => true,
			'data' => $result,
		));
		$view->setTerminal(true);
		return $view;
	}

	## Révision loyer CAF
	public function getNbrSousBlocRevisionCafAction(){
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$tools = new Tools();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);
		if ($request->isXmlHttpRequest()) {
			$nbrRows = 0;
			$success = true;
			$sg = "";
			if (isset($_FILES['cafRevisionFile']['tmp_name'])) {
				$rows = array();
				$i = 0;
				$fileName = '';
				if($_FILES['cafRevisionFile']['tmp_name'] != ''){
					$fileName = $_FILES['cafRevisionFile']['tmp_name'];
				}else{
					//on regarde si on a un fichier sauvegarder
					$fichierCaf = $this->getCafTable($gestId)->getFichierCaf($gestId);
					if($fichierCaf){
						$fileName = getcwd()."/public/docs/caf/".$fichierCaf;
					}
				}
				if(!$fileName){
					$view = new JsonModel(array(
						'success' => false,
						'nbrRows' => 0,
						'msg'	  => "Fichier vide ou incorrect",
					));
					$view->setTerminal(true);
					return $view;
				}
				if (($handle = fopen($fileName, "r")) !== false) {
					if($_FILES['cafRevisionFile']['tmp_name'] != ''){
						## On save le fichier CAF
						if (!is_dir(getcwd()."/public/docs")) {
							mkdir(getcwd()."/public/docs");
						}
						if (!is_dir(getcwd()."/public/docs/caf")) {
							mkdir(getcwd()."/public/docs/caf");
						}
						$folder = "./public/docs/caf";

						$extension = pathinfo($_FILES['cafRevisionFile']['name'], PATHINFO_EXTENSION);
						$filename = pathinfo($_FILES['cafRevisionFile']['name'], PATHINFO_FILENAME);
						$champName = $tools->removeAccent($filename);//$field->libelle;

						$fichierCaf = date('Ymd')."_".$champName."_".$gestId.".".$extension;
						if (move_uploaded_file($_FILES['cafRevisionFile']['tmp_name'], $folder.'/'.$fichierCaf)) {
							$this->getCafTable()->saveCafFile($gestId, $fichierCaf);
						}else{
							$success = false;
							$msg = "Erreur enregistrement fichier";
						}
					}
					## Fin save fichier CAF
					while (($data = fgets($handle, 205)) !== false) {
						$type = substr($data, 0, 2);
						if ($type == 03) {
							$nbrRows++;
						}
					}
				}
				fclose($handle); // fermeture du fichier
			}
			$view = new JsonModel(array(
					'success' => $success,
					'nbrRows' => $nbrRows,
					'msg'	  => $msg,
				));
				$view->setTerminal(true);
				return $view;
		}
		exit();
	}

	public function loadmodecafAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);

		if ($request->isXmlHttpRequest()) {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modecaf')
			->setVariables(array(
					'champModalHtml'	=> $this->loadChampsModal('caf'),
					'fichierCaf'		=> $this->getCafTable($gestId)->getFichierCaf($gestId),
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						  'htmlOP' => $htmlOutput,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	## not used
	public function loadRevisionLoyerCafAction(){
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			$allData = array();
			if (isset($_FILES['cafRevisionFile']['tmp_name'])) {
				$rows = array();
				$i = 0;
				if (($handle = fopen($_FILES['cafRevisionFile']['tmp_name'], "r")) !== false) {
					while (($data = fgets($handle, 205)) !== false) {
						// GET RECORD TYPE
						$type = substr($data, 0, 2);
						if ($type == 06) {
							$rows[$i]['code'] = $tools->removeAccentOnly(substr($data, 23, 13));
							## On ne prend en compte que les 8 derniers caractéres du numéro d'allocataire
							$rows[$i]['num'] = substr(substr($data, 36, 15), -8);
							$rows[$i]['nom'] = substr($data, 51, 20);
							$rows[$i]['prenom'] = substr($data, 71, 12);
							$i++;
						}
					}
				}
				fclose($handle); // fermeture du fichier
				$allData = $rows;
			}

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => '',
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Chargement de champs à remplir dans le formulaire de révision de loyer
	public function loadChampsCafRevisionAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);

		if ($request->isXmlHttpRequest()) {
			$cafAllocataire = $request->getPost('cafAllocataire','');
			$idResa = $request->getPost('idResa',0);
			$rowIndex = $request->getPost('rowIndex',0);
			$nomLocataire = $request->getPost('nomLocataire','');
			$prenomLocataire = $request->getPost('prenomLocataire','');

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modecafrevisionchamps')
			->setVariables(array(
				'cafAllocataire'=>$cafAllocataire,
				'idResa'=>$idResa,
				'rowIndex'=>$rowIndex,
				'nomLocataire'=>trim($nomLocataire),
				'prenomLocataire'=>trim($prenomLocataire),
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						 'htmlOP' => $htmlOutput,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	## validation formulaire révision loyer CAF
	public function validerFormRevisionCafAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);
		$msg = '';
		$success = true;
		if ($request->isXmlHttpRequest()) {
			$post = $request->getPost();
			$numSousBloc = $request->getPost('numSousBloc',0);
			$champs = $this->getCafTable()->getChampsARemplir();
			foreach($champs as $champName=>$opt){
				if(!empty($post[$champName]) && trim($post[$champName]) != ''){
					$champs[$champName]['value'] = $post[$champName];
				}
			}
			$champs['cafAllocataire']['value'] = $post['cafAllocataire']; 
			$ret = $this->getCafTable()->saveChampsCafToFile($gestId,$champs,$numSousBloc);
			if(is_array($ret) && !empty($ret)){
				$msg = implode('<br>',$ret);
				$success = false;
			}else{
				$msg = 'Validation bien faite';
			}

			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	## Télécharger le fichier caf modifier
	public function downloadCafFileAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);
		$msg = '';
		$success = true;
		if ($request->isXmlHttpRequest()) {
			$fichierCaf = $this->getCafTable()->getFichierCafMaj($gestId);
			if($fichierCaf){
				$cafFile = 'docs/caf/'.$fichierCaf;
			}else{
				$success = false;
				$msg = 'Aucun fichier CAF modifier trouvé.';
			}

			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'cafFile'=>$cafFile,
				));
			$view->setTerminal(true);
			return $view;
		}
	}

	## affichage liste caf mode révision loyer annuelle
	public function affichercafAction(){
		$request = $this->getRequest();
		$tools = new Tools();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);
		if ($request->isXmlHttpRequest()) {
			$jsonCafDatatableState = $request->getPost('jsonCafDatatableState', array());
			$numSousBloc = $request->getPost('numSousBloc', 0);

			$jsonCafDatatableFrom  = 'POST';
			if (empty($jsonCafDatatableState)) {
				$jsonCafDatatableState = $this->getCafTable()->loadState($gestId);
				$jsonCafDatatableFrom  = 'BDD';
			}
			//print_r($jsonCafDatatableState);

			$jsonCafDatatableFilter = array_key_exists('filter', $jsonCafDatatableState) ? $jsonCafDatatableState['filter'] : [];

			// Valeurs uniques pour les différents selects
			$selectOptions	= array();

			// Constitution d'une liste des lignes
			$rowsAll = $listeChampsAffiches = array();

			if ($jsonCafDatatableFilter) {
				// Initialisation de la liste des champs
				$formFields     = $this->getResaFields(0,$jsonCafDatatableFilter);
				$formFields['cafFields'] = $this->getCafTable()->getCafFields($jsonCafDatatableFilter)['cafFields'];

				// Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				$listeChampsAffiches    = $this->getlisteChampsAffiches($jsonCafDatatableFilter, $formFields);
				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$options = array('gestId'=>$gestId,'numSousBloc'=>$numSousBloc);
				$rowsAll = $this->getCafTable()->getListeWithAllFields($adapter, $listeChampsAffiches, array(), $options);

				// Constitution de la liste des options
				if ($rowsAll) {
					foreach ($rowsAll as $_key => $_row) {
						foreach ($_row as $_colName => $_value) {
							if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
								}
								$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
								if (!$_options || !in_array($_value, $_options)) {
									$selectOptions[$_colName][] = $_value;
								}
							} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($_value) {
									$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
									if(!empty($valsArr)) {
										foreach($valsArr as $k => $v) {
											$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
											if (!$_options || !in_array($v, $_options)) {
												$selectOptions[$_colName][] = $v;
											}
										}
									}
								}
							}
						}
					}
				}

				// Tri de ces options dans l'ordre alphabétique
				foreach ($selectOptions as $_colName => $_options) {
					sort($selectOptions[$_colName], SORT_STRING);
				}
			}



			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/modecafrevisiontable')
				->setVariables(array(
					'rows' 		=> array(),
					'resaFields' 	=> isset($formFields) ? $formFields['resaFields'] : array(),
					'cafFields' 	=> isset($formFields) ? $formFields['cafFields'] :array(),
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'				=> 1,
					'jsonCafDatatableState' => $jsonCafDatatableState,
					'selectOptions'	=> $selectOptions,
					'typeListe' => $typeListe,
					'champsNonModifiables'	=> $this->getChampsNonModifiable(),
					'config' => $this->getConfigurationTable()->getConfig(1),
				));

			$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'champs' => $listeChampsAffiches,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function savestatecafAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getCafTable()->setAdapter($adapter);
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonDatatableState = $request->getPost('jsonCafDatatableState', array());

			$this->getCafTable()->saveState($gestId, $jsonDatatableState);

			$view = new JsonModel(['success' => true]);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function getServerJsonDataCafAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);
		$this->getCafTable()->setAdapter($adapter);
		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');
			$numSousBloc = $request->getPost('numSousBloc',0);
			$typeListe  = '';

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('data' => [], 'draw' => 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);
			/*$view = new JsonModel($output);
			$view->setTerminal(true);
			return($view);*/

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonCafDatatableState		= $this->getCafTable()->loadState($gestId);
			$jsonCafDatatableFilter	= $jsonCafDatatableState ? $jsonCafDatatableState['filter'] : [];

			if (is_array($jsonCafDatatableFilter) && $columns) {
				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getResaFields(0,$jsonCafDatatableFilter);
				$formFields['cafFields'] = $this->getCafTable()->getCafFields($jsonCafDatatableFilter)['cafFields'];

				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$listeChampsAffiches	= array(
					'idLocataire' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
					'idReservation' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
				);

				foreach ($columns as $_key => $_column) {
					$_colName	= $_column['data'];
					if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
						## Recherche du champ dans les différentes listes de champs
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($formFields as $_typeField => $_fields) {
							if ($_typeField == "activeFields") {
								continue;
							}
							$_field = array_key_exists($_colName, $_fields) ? $_fields[$_colName] : null;
							if ($_field) {
								if ($_typeField == 'dynFields') {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->idChamp,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								} else {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->id,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								}
								break;
							}
						}
					}
				}

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where	= "";
				$options = array('gestId'=>$gestId,'numSousBloc'=>$numSousBloc);
				$rowsAll = $this->getCafTable()->getListeWithAllFields($adapter, $listeChampsAffiches, $where, $options);


				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);

				if ($rowsAll) {
					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					$selectVals = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
								$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					if ($colDates || !empty($selectVals)) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							if ($colDates) {
								foreach ($colDates as $_colName) {
									$rowValue	= $row[$_colName];
									if ($rowValue && strpos($rowValue, '-') == 2) {
										## Date au format dd-mm-yyyy -> il faut convertir
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $rowValue);
										$row[$_colName]		= "$yyyy-$mm-$dd";
									}
								}
							}
							##Select multiple
							if(!empty($selectVals)) {
								foreach($selectVals as $_colName => $sVals) {
									$rowValue	= $row[$_colName];
									if($rowValue) {
										$rowValueArr = explode(',', $rowValue);
										if(!empty($rowValueArr)) {
											$rowValueNew = '';
											foreach($rowValueArr as $v) {
												$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
												$rowValueNew .= ', ';
											}
											$rowValueNew = substr($rowValueNew, 0, -2);
											if($rowValueNew) {
												$row[$_colName]	= $rowValueNew;
											}
										}
									}
								}
							}
							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}

					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonCafDatatableFilter as $fieldName => $field) {
						$searchTypes[$fieldName]	= $field['type'];
						if (in_array($fieldName, $colRadios)) {
							$searchTypes[$fieldName]	= "text";
						}//traiter les champs radio comme des text
						if (in_array($fieldName, $colCheckbox)) {
							$searchTypes[$fieldName]	= "checkbox";
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));

					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column['name'];
						$value		= $column['search']['value'];
						if ($colName && $column['searchable'] && $value) {
							$searchType	= $searchTypes[$colName];
							if ($searchType == 'date' || $searchType == 'number') {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max)		= explode("|", $value);
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['min']		= $min;
								$searchs[$colName]['max']		= $max;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['text']	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search['min'] && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'number') {
									if ($search['min'] != '' && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] != '' && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}


					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}

				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
			}

			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;

			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}


	public function saveFormFieldsAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$user = $auth->getIdentity();
		if ($request->isXmlHttpRequest()) {
			$type = $request->getPost('type');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : type=$type");
			$savedState = json_encode($request->getPost('savedState'));
			$data = $this->getTableObjet('champs_demandes_save')->select(array('type' => $type))->current();
			if ($data) {
				$this->getTableObjet('champs_demandes_save')->update(array('fields' => $savedState), array('type' => $type));
			} else {
				$this->getTableObjet('champs_demandes_save')->insert(array('fields' => $savedState, 'type' => $type));
			}

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "SAVE LISTE par l'utilisateur".$gestId." type: ".$type;
			$log->dataBefore = $data;
			$log->dataAfter = $savedState;
			$log->tableName = "champs_demandes_save";
			$this->getLogsTable()->saveLogs($log);

			$view = new JsonModel(array(
				'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	## Archivage demande
	public function archiverdemandeAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$idType = $request->getPost('idType');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idType=$idType ids=".json_encode($ids));
			$success = false;
			if (!empty($ids) && $idType) {
				foreach ($ids as $id) {
					//$demandesDeResa = $this->getDemandesTable()->getDemandesByResaAndType($idResa,$idType);
					//foreach($demandesDeResa as $dem){
					$this->getDemandesTable()->archiverDemande($id);
					//}
				}
				$success = true;
			}

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "Archivage demandes ".$dateOperation;
			$log->dataBefore = array();
			$log->dataAfter = $ids;
			$log->tableName = "demandes";
			$this->getLogsTable()->saveLogs($log);

			$view = new JsonModel(array(
						'success' => $success,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Désarchivage demande
	public function desarchiverdemandeAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$idType = $request->getPost('idType');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idType=$idType ids=".json_encode($ids));
			$success = false;
			if (!empty($ids) && $idType) {
				foreach ($ids as $id) {
					//$demandesDeResa = $this->getDemandesTable()->getDemandesByResaAndType($idResa,$idType);
					//foreach($demandesDeResa as $dem){
					$this->getDemandesTable()->desarchiverDemande($id);
					//}
				}
				$success = true;
			}


			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "Désarchivage demandes ".$dateOperation;
			$log->dataBefore = array();
			$log->dataAfter = $ids;
			$log->tableName = "demandes";
			$this->getLogsTable()->saveLogs($log);

			$view = new JsonModel(array(
						'success' => $success,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Suupression définitive demande
	public function supprimerdemandeAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$idType = $request->getPost('idType');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idType=$idType ids=".json_encode($ids));
			$success = false;
			$demandes = array();
			if (!empty($ids) && $idType) {
				foreach ($ids as $id) {
					//$demandesDeResa = $this->getDemandesTable()->getDemandesByResaAndType($idResa,$idType);
					//foreach($demandesDeResa as $dem){
					$dem = $this->getDemandesTable()->getDemande($id);
					if($dem){
						$demandes[] = $dem;
						$this->getDemandesTable()->supprimerDemande($id);
					}
					//}
				}
				$success = true;
			}

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "Suppression demandes ".$dateOperation;
			$log->dataBefore = $demandes;
			$log->dataAfter = $ids;
			$log->tableName = "demandes";
			$this->getLogsTable()->saveLogs($log);

			$view = new JsonModel(array(
						'success' => $success,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Archivage colis
	public function archivercolislisteAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		if ($request->isXmlHttpRequest()) {
			$idsColis = $request->getPost('ids');
			$success = false;
			if (!empty($idsColis)) {
				foreach ($idsColis as $id) {
					$this->getTableObjet('colis')->update(array('archive' => 1), array('id' => $id));
				}
				$success = true;
			}

			$view = new JsonModel(array(
						'success' => $success,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function getFormHtmlFieldsAction()
	{
		$request = $this->getRequest();
		$success = false;
		$html = null;
		if ($request->isXmlHttpRequest()) {
			$idDemande	= $request->getPost('idDemande');
			$type		= $request->getPost('type');
			$field		= $request->getPost('field');

			$demande = $this->getDemandesTable()->getDemande($idDemande);

			if ($type === 'resa' && $demande['idResa']) {
				$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
				$select = $tableObj->getTable()->getSql()->select();
				$select->where('(idTheme = 1 OR idTheme = 2) AND code = "'.$field.'"');
				$champ = $tableObj->getTable()->selectWith($select)->current();
				$value = $this->getResaTable()->getResaList($demande['idResa'])->current()->$field;

				$html = $this->getInput($champ->equivalentSql, 1, 1, $value);
			} elseif ($type === 'demande') {
				$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
				$select = $tableObj->getTable()->getSql()->select();
				$select->where('idTheme = 5 AND code = "'.$field.'"');
				$champ = $tableObj->getTable()->selectWith($select)->current();
				$champ->idType = $champ->idTypeHtml;
				$champ->dynamic = false;

				$value = $demande[$champ->equivalentSql];

				$html = $this->getDemandeInput($champ, $value, $idDemande);
			} elseif ($type === 'dynamicDemande') {
				$tableObj = new Tables('champs_demandes', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
				$select = $tableObj->getTable()->getSql()->select();
				$select->where('equivalentSql = "'.$field.'" AND idModele = '.$demande['idModele']);
				$champ = $tableObj->getTable()->selectWith($select)->current();
				$champ->dynamic = true;

				$table = $this->getTableObjet('demandes_values');
				$select = $table->getSql()->select();
				if ($champ->idType == 3) {
					$select->join('valeurs_select', 'valeurs_select.id = demandes_values.valeur', array('vs_valeur' => 'valeur'), 'LEFT');
				}
				$select->where(array('demandes_values.idDemande' => $idDemande, 'demandes_values.idChamp' => $champ->id));
				$dv = $table->selectWith($select)->current();
				if ($champ->idType == 3) {
					$value = $dv->vs_valeur;
				} else {
					$value = $dv->valeur;
				}

				$html = $this->getDemandeInput($champ, $value, $idDemande);
			} else {
				$view = new JsonModel(array(
					'success' => $success,
					'htmlOP' => $html,
				));
				$view->setTerminal(true);
				return $view;
			}
			$success = true;
		}

		$view = new JsonModel(array(
			'success' => $success,
			'htmlOP' => $html,
		));
		$view->setTerminal(true);
		return $view;
	}

	private function getDemandeInput($champ, $value, $idDemande)
	{
		$html = null;
		$tools = new Tools();
		if (!$champ->dynamic && $champ->idType == 3) {
			if ($champ->code === 'demande_etat') {
				$html .= $this->createDemandeStatus($champ->equivalentSql, $value);
			} elseif ($champ->code === 'demande_affectedTo_display_name') {
				$html .= $this->createDemandeAffectation($champ->equivalentSql, $value);
			}
		} else {
			// TEXT
			if ($champ->idType == 1) {
				$html .= '<input type=\'text\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// DATE
			elseif ($champ->idType == 2) {
				$extraMinDate = $extraMaxDate = null;
				$extraDate = $this->getTableObjet('champs_demandes_dateinterval')->select(array('idChamp' => $champ->id))->current();

				$html .= '<input type=\'text\' id=\''.$champ->equivalentSql.$idDemande.'\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';

				$plages = $tools->getPlagesDatesBO($extraDate);
				extract($plages);

				$html .= '<script>
							$(\'#'.$champ->equivalentSql.$idDemande.'\').datepicker({
								startDate:\''.$extraMinDate.'\',
								endDate:\''.$extraMaxDate.'\'
							});
						</script>';
			}

			// LIST
			elseif ($champ->idType == 3) {
				//$select = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$select = $this->getSelectOptions($champ->sourceListe, array(), array('valeurBdd' => $value));
				$html .= '<select class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\'>';
				foreach ($select as $option) {
					$html .= '<option value=\''.$option->id.'\' '.($value == $option->id ? 'selected' : '').'>'.$option->valeur.'</option>';
				}
				$html .= '</select>';
			}

			// DOC
			elseif ($champ->idType == 4) {
				$html .= '<input type=\'file\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// NB
			elseif ($champ->idType == 5) {
				$html .= '<input type=\'number\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// EMAIL
			elseif ($champ->idType == 6) {
				$html .= '<input type=\'email\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// TEXTAREA
			elseif ($champ->idType == 7) {
				$html .= '<textarea class=\'form-control type_7 editable-input\' name=\''.$champ->equivalentSql.'\' rows=\''.$champ->tailleRow.'\' cols=\''.$champ->tailleColumn.'\'>'.$value.'</textarea>';
			}

			// CHECKBOX
			elseif ($champ->idType == 8) {
				$html .= '<input name=\''.$champ->equivalentSql.'\' type=\'checkbox\' value=\'1\' '.($value ? 'checked' : '').'> '.$champ->libelle;
			}

			// RADIO
			elseif ($champ->idType == 9) {
				//$radios = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$radios = $this->getSelectOptions($champ->sourceListe);
				$html .= '<label style=\'width:100%;\'>'.$champ->libelle.'</label>';
				foreach ($radios as $option) {
					$html .= '<div style=\'width:100%;\'>';
					$html .= '<input id=\''.$option->id.'\' name=\''.$champ->equivalentSql.'\' type=\'radio\' value=\''.$option->id.'\' '.($value == $option->valeur ? 'checked' : '').'>'.$option->valeur;
					$html .= '</div>';
				}
			}

			// HTML
			elseif ($champ->idType == 10) {
				$html .= '<p>'.$champ->description.'</p>';
			}

			// PASS
			elseif ($champ->idType == 11) {
				$html .= '<input type=\'password\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\'>';
			}
		}
		return $html;
	}

	private function getColisInput($champ, $value, $idColis)
	{
		$html = null;
		$tools = new Tools();
		if (!$champ->dynamic && $champ->idType == 3) {
		} else {
			// TEXT
			if ($champ->idType == 1) {
				$html .= '<input type=\'text\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// DATE
			elseif ($champ->idType == 2) {
				$extraMinDate = $extraMaxDate = null;
				$extraDate = $this->getTableObjet('champs_colis_dateinterval')->select(array('idChamp' => $champ->id))->current();

				$html .= '<input type=\'text\' id=\''.$champ->equivalentSql.$idColis.'\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';

				$plages = $tools->getPlagesDatesBO($extraDate);
				extract($plages);

				$html .= '<script>
							$(\'#'.$champ->equivalentSql.$idColis.'\').datepicker({
								startDate:\''.$extraMinDate.'\',
								endDate:\''.$extraMaxDate.'\'
							});
						</script>';
			}

			// LIST
			elseif ($champ->idType == 3) {
				$select = $this->getTableObjet('valeurs_select')->select(array('idSelect' => $champ->sourceListe, 'deleted' => '0'));
				$html .= '<select class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\'>';
				foreach ($select as $option) {
					$html .= '<option value=\''.$option->id.'\' '.($value == $option->id ? 'selected' : '').'>'.$option->valeur.'</option>';
				}
				$html .= '</select>';
			}

			// DOC
			elseif ($champ->idType == 4) {
				$html .= '<input type=\'file\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// NB
			elseif ($champ->idType == 5) {
				$html .= '<input type=\'number\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// EMAIL
			elseif ($champ->idType == 6) {
				$html .= '<input type=\'email\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\' value=\''.$value.'\'>';
			}

			// TEXTAREA
			elseif ($champ->idType == 7) {
				$html .= '<textarea class=\'form-control type_7 editable-input\' name=\''.$champ->equivalentSql.'\' rows=\''.$champ->tailleRow.'\' cols=\''.$champ->tailleColumn.'\'>'.$value.'</textarea>';
			}

			// CHECKBOX
			elseif ($champ->idType == 8) {
				$html .= '<input name=\''.$champ->equivalentSql.'\' type=\'checkbox\' value=\'1\' '.($value ? 'checked' : '').'> '.$champ->libelle;
			}

			// RADIO
			elseif ($champ->idType == 9) {
				$radios = $this->getTableObjet('valeurs_select')->select(array('idSelect' => $champ->sourceListe, 'deleted' => '0'));
				$html .= '<label style=\'width:100%;\'>'.$champ->libelle.'</label>';
				foreach ($radios as $option) {
					$html .= '<div style=\'width:100%;\'>';
					$html .= '<input id=\''.$option->id.'\' name=\''.$champ->equivalentSql.'\' type=\'radio\' value=\''.$option->id.'\' '.($value == $option->valeur ? 'checked' : '').'>'.$option->valeur;
					$html .= '</div>';
				}
			}

			// HTML
			elseif ($champ->idType == 10) {
				$html .= '<p>'.$champ->description.'</p>';
			}

			// PASS
			elseif ($champ->idType == 11) {
				$html .= '<input type=\'password\' class=\'form-control editable-input\' name=\''.$champ->equivalentSql.'\'>';
			}
		}
		return $html;
	}

	public function getDpFields($idListe = 0, $jsonResaDatatableFilter = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe");

		$configFilter = $this->getConfigFiltersTable()->getListeFilter($idListe, 'dp');

		$champsTranslations = $this->getAllChampsTranslation();
		$dpFields = $dynFields = array();
		$activeFields = ['dpRow' => [], 'dynRow' => []];

		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		# Liste des champs fixes par thèmes
		# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$select1 = $tableObj->getTable()->getSql()->select();
		#$select1->where('idTheme = 1 OR idTheme = 2 OR idTheme = 3');
		$select1->where('idTheme IN (1,2,3,4,5,6,7,8,9)');
		$select1->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select1);

		$champsNonTraduite = array('residence', 'numeroChambre');

		$typesSuivis = array();
		$tsRows = $this->getTableObjet('type_suivi')->select();
		foreach ($tsRows as $ts) {
			$typesSuivis[$ts->id] = $ts;
		}
		if ($themeResult) {
			foreach ($themeResult as $row) {
				if ($row->idTheme == 2 && $row->table == 'suivis') {
					$champSquivalentSql = $row->equivalentSql;
					$champCode = $row->code;
					$champNom = $row->nom;
					foreach ($typesSuivis as $ts) {
						$rowN = clone $row;
						$code = $champCode."_TS_".$ts->id;
						$nom = $champNom . " (".$ts->type.")";
						$equivalentSql = $champSquivalentSql;//."_TS_".$ts->id;
						if ($jsonResaDatatableFilter) {
							$activeFields['dpRow'][$code] =
							$rowN->checked = array_key_exists($code, $jsonResaDatatableFilter);
						}
						$rowN->code = $code;
						$rowN->idTypeSuivis = $ts->id;
						$rowN->nom = $nom;
						$rowN->equivalentSql = $equivalentSql;
						$rowN->hasDynFilter = (!empty($configFilter) && array_key_exists($equivalentSql, $configFilter)) ? '1' : '';
						if (array_key_exists($equivalentSql, $champsTranslations) && !in_array($code, $champsNonTraduite) && substr($champsTranslations[$rowN->equivalentSql], 0, 2) != 'l_') {
							$rowN->nom = $champsTranslations[$equivalentSql];
						}

						if ($jsonResaDatatableFilter[$row->equivalentSql]['libelle'] && trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']) != '') {
							$rowN->nom = trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']);
						}

						$dpFields[$code] = $rowN;
					}
				} else {
					if ($jsonResaDatatableFilter) {
						$activeFields['dpRow'][$row->code] = $row;
						$row->checked = array_key_exists($row->code, $jsonResaDatatableFilter);

						// var_dump($activeFields['dpRow'][$row->code]);die();
					}
					$row->hasDynFilter = (!empty($configFilter) && array_key_exists($row->equivalentSql, $configFilter)) ? '1' : '';
					if (array_key_exists($row->equivalentSql, $champsTranslations) && !in_array($row->code, $champsNonTraduite) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$row->nom = $champsTranslations[$row->equivalentSql];
					}

					if ($jsonResaDatatableFilter[$row->equivalentSql]['libelle'] && trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']) != '') {
						$row->nom = trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']);
					}

					if ($row->code != 'idUserDp') {
						$dpFields[$row->code] = $row;
					}
				}
			}
		}
		// print_r($dpFields);exit();

		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique($full = true, true);
		if ($champsDynamiques) {
			foreach ($champsDynamiques as $row) {
				if($row->idChampSuivis > 0) {
					continue;
				}
				$_code	= $row->equivalentSql;

				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;
					$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($_code, $configFilter)) ? '1' : '';
					$dynFields[$_code] = $obj;
				} else {
					if($row->idType == 19) {
						$row->idType = $this->getGlobalHelper()->getTypeChampFormuleDate($row->id);
					}
					$obj = new \stdClass();
					$obj->table = 'champs_dynamiques';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['dpRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}

					if ($jsonResaDatatableFilter[$row->equivalentSql]['libelle'] && trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']) != '') {
						$obj->nom = trim($jsonResaDatatableFilter[$row->equivalentSql]['libelle']);
					}

					$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($_code, $configFilter)) ? '1' : '';
					$dynFields[$obj->code] = $obj;
				}
				if ($_code == 'idUserDp' && false) {
					$field = $dynFields['idUserDp'];
					$field->table = 'domiciliations';
					$dynFields[$_code] = $field;
				}
			}
		}

		## champs catalogue
		$tableCF = $this->getTableObjet('champs_formulaires');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'standard' AND equivalentSql LIKE 'catalogues_%'");
		$resultSet = $tableCF->selectWith($select);
		foreach ($resultSet as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->equivalentSql = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idType = $row->idType;
			$obj->idTypeHtml = $row->idType;
			$obj->table = 'catalogue_dp';
			if ($jsonResaDatatableFilter) {
				$activeFields['dpRow'][$obj->code] =
				$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
			}
			$obj->hasDynFilter = (!empty($configFilter) && array_key_exists($_code, $configFilter)) ? '1' : '';
			$dynFields[$obj->code] = $obj;
		}

		## champs suivis
		$tableCF = $this->getTableObjet('champs_suivis');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'libre'");
		$champsSuivis = $tableCF->selectWith($select);

		if ($champsSuivis) {
			foreach ($champsSuivis as $row) {
				$_code	= $row->equivalentSql;

				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;
					$dynFields[$_code] = $obj;
				} else {
					if($row->idType == 19) {
						$row->idType = $this->getGlobalHelper()->getTypeChampFormuleDate($row->id, 'suivis');
					}
					$obj = new \stdClass();
					$obj->table = 'champs_suivis';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idTypeSuivis = $row->idTypeSuivis;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['dpRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations) && substr($champsTranslations[$row->equivalentSql], 0, 2) != 'l_') {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}
					$dynFields[$obj->code] = $obj;
				}
			}
		}

		## champs dynamiques catalogie
		$tableCF = $this->getTableObjet('champs_catalogue');
		$select = $tableCF->getSql()->select();
		$select->where(" nature = 'libre'");
		$champsCatalogues = $tableCF->selectWith($select);

		if ($champsCatalogues) {
			foreach ($champsCatalogues as $row) {
				$_code	= $row->equivalentSql;

				if (array_key_exists($_code, $dynFields)) {
					## L'entrée existe déjà et il suffit de rajouter l'id du champ
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$obj = $dynFields[$_code];
					$obj->idChamp[]	= $row->id;
					$dynFields[$_code] = $obj;
				} else {
					$obj = new \stdClass();
					$obj->table = 'champs_catalogue';
					$obj->code = $row->equivalentSql;
					$obj->id = $row->id;
					$obj->nom = $row->libelle;
					$obj->idTypeHtml = $row->idType;
					$obj->idTypeCatalogue = $row->idTypeCatalogue;
					$obj->idChamp = array($row->id);
					$obj->sourceListe = $row->sourceListe;
					$obj->equivalentSql = $row->equivalentSql;
					$obj->options = $row->options;
					if ($jsonResaDatatableFilter) {
						$activeFields['dpRow'][$obj->code] =
						$obj->checked = array_key_exists($obj->code, $jsonResaDatatableFilter);
					}
					if (array_key_exists($row->equivalentSql, $champsTranslations)) {
						$obj->nom = $champsTranslations[$row->equivalentSql];
					}
					$dynFields[$obj->code] = $obj;
				}
			}
		}


		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dpFields=".json_encode(array_keys($dpFields)));
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : keys_dynFields=".json_encode(array_keys($dynFields)));

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dpFields=".json_encode($dpFields));
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dynFields=".json_encode($dynFields));
		return array(
			'dpFields' 	=> $dpFields,
			'dynFields' 	=> $dynFields,
			'activeFields'	=> $activeFields,
		);
	}

	public function getFormFields($modeleId = 0, $jsonFormDatatableState = array())
	{
		if (!is_array($jsonFormDatatableState)) {
			$jsonFormDatatableState = array();
		}//bug array_key_exists si null
		$locFields = $resaFields = $dpFields = $demFields = $dynFields = array();
		$theme1Result = $theme2Result = $theme3Result = $theme4Result = null;

		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$select1 = $tableObj->getTable()->getSql()->select();
		$select1->where('idTheme = 1 OR idTheme = 2 OR idTheme = 5 OR idTheme = 9');
		$select1->order(array('ordre ASC'));
		$themeResult = $tableObj->getTable()->selectWith($select1);

		if ($modeleId) {
			$tableObj = new Tables('champs_demandes', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			$select4 = $tableObj->getTable()->getSql()->select();
			$select4->where(array('idModele' => $modeleId));
			$theme4Result = $tableObj->getTable()->selectWith($select4);
		}

		// GET DEMANDE DYNAMIC FIELDS
		if ($modeleId) {
			foreach ($theme4Result as $row) {
				$obj = new \stdClass();
				$obj->code = $row->equivalentSql;
				$obj->id = $row->id;
				$obj->nom = $row->libelle;
				$obj->idTypeHtml = $row->idType;
				$obj->checked = array_key_exists('dynDem', $jsonFormDatatableState) && array_key_exists($obj->code, $jsonFormDatatableState['dynDem']);
				$dynFields[$obj->code] = $obj;
			}
		}

		if ($jsonFormDatatableState['code'] == 'dp') {
			$arrayLoc = [];
			foreach ($themeResult as $row) {
				$row->checked = false;
				if ($row->table == 'domiciliations') {
					if (array_key_exists('code', $jsonFormDatatableState)) {
						$row->checked = true;
						$dpFields[$row->code] = $row;
					}
				} elseif ($row->table == 'locataires') {
					foreach ($jsonFormDatatableState as $key => $valeur) {
						if ($key == $row->code) {
							$row->checked = true;
						}
					}
					$locFields[$row->code] = $row;
				}
			}
		} else {
			foreach ($themeResult as $row) {
				if ($row->idTheme == 1) {
					$row->checked = array_key_exists('resa', $jsonFormDatatableState) && array_key_exists($row->code, $jsonFormDatatableState['resa']);
					$locFields[$row->code] = $row;
				} elseif ($row->idTheme == 2) {
					$row->checked = array_key_exists('resa', $jsonFormDatatableState) && array_key_exists($row->code, $jsonFormDatatableState['resa']);
					$resaFields[$row->code] = $row;
				} elseif ($row->idTheme == 5) {
					$row->checked = array_key_exists('dem', $jsonFormDatatableState) && array_key_exists($row->code, $jsonFormDatatableState['dem']);
					$demFields[$row->code] = $row;
				}
			}
		}


		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		foreach ($champsDynamiques as $row) {
			// if ($row->name == 'libre_Travailleur_sociale') {
			// 	var_dump($row);die();
			// }
			if($row->idChampSuivis > 0) {
				continue;
			}

			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$obj->idTypeHtml = $row->idType;
			$obj->checked = array_key_exists('resa', $jsonFormDatatableState) && array_key_exists($obj->code, $jsonFormDatatableState['resa']);
			$dynFields[$obj->code] = $obj;

			foreach ($jsonFormDatatableState as $key => $value) {
				if ($key == $row->equivalentSql) {
					$obj->checked = true;
					$obj->sourceListe = $row->sourceListe;
				}
			}
		}

		return array(
			'locFields' 	=> $locFields,
			'resaFields' 	=> $resaFields,
			'demFields' 	=> $demFields,
			'dynFields' 	=> $dynFields,
			'dpFields' 	=> $dpFields,
		);
	}

	## les logs pas coli, appeler quand on clique sur l affichage des logs dasn la list des colis, onglet colis de la fiche locataire
	public function getlogscolisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idColis = $request->getPost('idColis');
			$htmlOP = "";
			$rows = array();
			$rows = $this->getTableObjet('colis_historique')->select(array('idColis' => $idColis));

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/colislogs')
			->setVariables(array(
				'rows' => $rows,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## fonction archive colis
	public function archivercolisAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$user = $auth->getIdentity();
		if ($request->isXmlHttpRequest()) {
			$idColis = $request->getPost('idColis');
			$idResa = $request->getPost('idResa');
			$msg = "Erreur suppresion coli";
			$success = false;
			$msgClass = "danger";
			if ($idColis && $idResa) {
				$this->getTableObjet('colis')->update(array('deleted' => 1), array('id' => $idColis));
				$msg = "Coli bien supprimé";
				$success = true;
				$msgClass = "success";
				$comment = ('Colis supprimé par "'.$user->getDisplayname().'"');
				$type = 'suppression colis';
				$this->getTableObjet('colis_historique')->insert(array('idResa' => $idResa, 'type' => $type, 'commentaire' => $comment, 'idColis' => $idColis));
			}

			$view = new JsonModel(array(
				'success' 	=> $success,
				'msg'		=> $msg,
				'idColis' => $idColis,
				'msgClass' => $msgClass,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//appeler lors de l  edition de la colis dans l onglet colis de la fiche locataire
	public function editcolisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idColis = $request->getPost('idColis');
			$idResa = $request->getPost('idResa');
			$formHtml = "";
			$msg = "Erreur chargement";
			if ($idColis && $idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				$formHtml = $this->loadColisTab($resa, array('idColis' => $idColis));
				$msg = "Infos bien chargé";
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'msg'		=> $msg,
				'formHtml' => $formHtml,
				'idColis' => $idColis,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//rest le formulaire des colis pour un nouveau ajout
	public function resetcolisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$formHtml = "";
			$msg = "Erreur chargement, veuillez re essayer.";
			$success = false;
			$msgClass = "danger";
			if ($idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				$formHtml = $this->loadColisTab($resa, array('typeRetour' => 'reset'));
				$msg = "Veuillez remplir le formulaire et le valider";
				$success = true;
				$msgClass = "success";
			}

			$view = new JsonModel(array(
				'success'  => $success,
				'formHtml' => $formHtml,
				'msgClass' => $msgClass,
				'msg'	   => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//rechargement de la liste des colis apres validation
	public function loadtablecolisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$listeHtml = "";
			if ($idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				$listeHtml = $this->loadColisTab($resa, array('typeRetour' => 'tableau'));
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'listeHtml' => $listeHtml,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function loadColisTab($resa, $params = array())
	{
		$idColis = !empty($params['idColis']) ? $params['idColis'] : null;
		$typeRetour = !empty($params['typeRetour']) ? $params['typeRetour'] : "";
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=".$resa->id." idColis=$idColis");

		$data = array();
		$table = $this->getTableObjet('champs_colis');
		$select = $table->getSql()->select();
		$select->join('colis_values', 'colis_values.idChamp = champs_colis.id', array('dv_id' => 'id', 'dv_valeur' => 'valeur', 'dv_idColis' => 'idColis'));
		$select->join('valeurs_select', 'valeurs_select.idSelect = champs_colis.sourceListe AND valeurs_select.id = colis_values.valeur', array('vs_valeur' => 'valeur'), 'LEFT');
		$select->where(array('colis_values.idResa' => $resa->id));
		if ($idColis) {
			$select->where(array('colis_values.idColis' => $idColis));
		}
		$dvs = $table->selectWith($select);

		$dataListe = array();//valeur par colis
		foreach ($dvs as $dv) {
			$val = $dv->dv_valeur;
			$data[$dv->id] = $val;
			$dataListe[$dv->dv_idColis][$dv->id] = $dv->vs_valeur ? $dv->vs_valeur : $dv->dv_valeur;
		}

		$fieldsResult = $this->getTableObjet('champs_colis')->select();
		$fields = array();
		foreach ($fieldsResult as $f) {
			$fields[] = $f;
		}

		if ($typeRetour == "reset" || $typeRetour == "default") {
			//on vide le formulaire pour un nouveau ajout, ou quand on charge la fiche locataire pour la premier fois
			$data = array();
		}

		$returnForm = $this->buildColisForm($resa->id, $fields, $data);//return array html, validator
		$form = $returnForm['html'];
		$validator = !empty($returnForm['validator']) ? $returnForm['validator'] : array();

		//cas edition de la ligne colis du tableau listecolis, ou ajout d un nouveau colis
		if ($idColis || $typeRetour == "reset") {
			return $form;
		}


		//listes des colis
		$htmlViewLC = new ViewModel();
		$htmlViewLC->setTerminal(true)
		->setTemplate('reservation/liste/colisliste')
		->setVariables(array(
			"fields" => $fields,
			"data" => $dataListe,
			"colis" => $this->getColisByResa($resa->id),
		));
		$htmlLC = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewLC);

		if ($typeRetour == "tableau") {
			return $htmlLC;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/colisTab')
		->setVariables(array(
			"form" => $form,
			"htmlLC" => $htmlLC,
			'idResa' => $resa->id,
			"validator" => json_encode($validator, JSON_FORCE_OBJECT),
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	private function getColisByResa($idResa)
	{
		$tableColis = $this->getTableObjet('colis');
		$select = $tableColis->getSql()->select();
		$select->where(array('deleted' => 0, 'idResa' => $idResa));
		$select->order(array('id DESC'));
		$result = $tableColis->selectWith($select);
		return $result;
	}

	private function buildColisForm($idResa, $champs, $result)
	{
		$row = 0;
		$html = null;
		$tools = new Tools();

		$validator['locale'] = 'fr_FR';
		$validator['fields'] = array();

		foreach ($champs as $champ) {
			$extraOption = null;
			$validator['fields'][$champ->equivalentSql]['validators'] = array();
			if ($champ->obligatoire) {
				$extraOption .= ' required ';
			}

			if ($champ->obligatoire) {
				$extraOption .= ' required ';
				$validator['fields'][$champ->equivalentSql]['validators']['notEmpty'] = array();
			}

			if (!$champ->modifiable) {
				$extraOption .= ' disabled="disabled" readonly="readonly" ';
			}

			if ($row == 0) {
				$row = $champ->row;
			}

			if ($champ->row > $row) {
				$html .= '<div class="clearfix"></div>';
				$row = $champ->row;
			}
			$html .= '<div class="col-md-'. 4 * $champ->tailleColumn .'">';
			$html .= '<div class="form-group has-feedback">';

			// TEXT
			if ($champ->idType == 1) {
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// DATE
			elseif ($champ->idType == 2) {
				$extraMinDate = $extraMaxDate = null;
				$extraDate = $this->getTableObjet('champs_colis_dateinterval')->select(array('idChamp' => $champ->id))->current();
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' tabindex="-1">';

				$plages = $tools->getPlagesDatesBO($extraDate);
				extract($plages);

				$html .= '<script>
							$("#myColisContent #'.$champ->idCss.'").datepicker({
								"format" : "dd-mm-yyyy",
								startDate:\''.$extraMinDate.'\',
								endDate:\''.$extraMaxDate.'\',
								autoclose:true,
							});
						</script>';
			}

			// LIST
			elseif ($champ->idType == 3) {
				//$select = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$valeurBdd = (array_key_exists($champ->id, $result) && $result[$champ->id]) ? $result[$champ->id] : null;
				$select = $this->getSelectOptions($champ->sourceListe, array(), array('valeurBdd' => $valeurBdd));
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<select class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';
				foreach ($select as $option) {
					$html .= '<option value="'.$option->id.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id] == $option->id ? 'selected' : '').' >'.$option->valeur.'</option>';
				}
				$html .= '</select>';
			}

			// DOC
			elseif ($champ->idType == 4) {
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="file" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// NB
			elseif ($champ->idType == 5) {
				$min = $champ->valeurMin ? 'min="'.$champ->valeurMin.'"' : "";
				$max = $champ->valeurMax ? 'max="'.$champ->valeurMax.'"' : "";
				if ($champ->valeurMin) {
					$validator['fields'][$champ->equivalentSql]['validators']['greaterThan'] = array('value' => $champ->valeurMin);
				}
				if ($champ->valeurMax) {
					$validator['fields'][$champ->equivalentSql]['validators']['lessThan'] = array('value' => $champ->valeurMax);
				}

				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="number" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' '.$min.' '.$max.' >';
			}

			// EMAIL
			elseif ($champ->idType == 6) {
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="email" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// TEXTAREA
			elseif ($champ->idType == 7) {
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<textarea class="form-control type_7" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" rows="'.$champ->tailleRow.'" cols="'.$champ->tailleColumn.'" '.$extraOption.' >'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'"</textarea>';
			}

			// CHECKBOX
			elseif ($champ->idType == 8) {
				$html .= '<input id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" type="checkbox" value="1" '.(array_key_exists($champ->id, $result) && $result[$champ->id] ? 'checked' : '').'  '.$extraOption.' > '.$champ->libelle;
			}

			// RADIO
			elseif ($champ->idType == 9) {
				//$radios = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$radios = $this->getSelectOptions($champ->sourceListe);
				$html .= '<label style="width:100%;">'.$champ->libelle.'</label>';
				foreach ($radios as $option) {
					$html .= '<div style="width:100%;">';
					$html .= '<input id="'.$option->id.'" name="'.$champ->equivalentSql.'" type="radio" value="'.$option->id.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id] == $option->id ? 'checked' : '').' '.$extraOption.' >'.$option->valeur;
					$html .= '</div>';
				}
			}

			// HTML
			elseif ($champ->idType == 10) {
				$html .= '<p>'.$champ->description.'</p>';
			}

			// PASS
			elseif ($champ->idType == 11) {
				$html .= '<label for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="password" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';
			}

			$html .= '</div>';
			$html .= '</div>';
		}

		// VALIDATION BUTTON
		$html .= '<div class="clearfix"></div>';

		$html .= '<div class="col-md-12">
						<input type="hidden" name="idResa" value="'.$idResa.'">
				</div>';
		return array('html' => $html, 'validator' => $validator);
	}


	private function getSelectOptions($sourceListe, $champOptions = null, $params = array())
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$idResa = !empty($params['idResa']) ? $params['idResa'] : null;
		$idDp = !empty($params['idDp']) ? $params['idDp'] : null;
		$valeurBdd = !empty($params['valeurBdd']) ? $params['valeurBdd'] : null;

		$gestId = null;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$idResidenceUser = null;
		$idCampagne = null;
		if($sourceListe == "user") {
			if($idResa) {
				$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
				if($resa) {
					$idCampagne = $resa->idCampagne;
					if ($resa->idLogement) {
						$residenceDeLogement = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						$idResidenceUser = $residenceDeLogement->idResidence;
					} elseif ($resa->residenceOrientation) {
						$idResidenceUser = $resa->residenceOrientation;
					} else {
						$residenceDeCampagne = $this->getResidencesTable()->getResidenceDeCampagne($idCampagne);
						if($residenceDeCampagne) {
							$idResidenceUser = $residenceDeCampagne->id;
						}
					}
				}
			} elseif($idDp) {
				$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
				if($dp) {
					$idCampagne = $dp->idCampagne;
				}
			}
		}

		$options = array();
		if (is_numeric($sourceListe)) {
			$table = $this->getTableObjet('valeurs_select');
			$select = $table->getSql()->select();
			$select->where(array('idSelect' => $sourceListe/*,'deleted'=>'0'*/));
			$select->order(array('ordre', 'valeur'));
			$result = $table->selectWith($select);

			$autreRow = null;
			//mettre la valeur Autre en fin de la liste
			foreach ($result as $row) {
				if($row->deleted == '1') {
					if($valeurBdd && $row->id == $valeurBdd) {
						//on laisse la valeur deleted
					} else {
						continue;
					}
				}

				if (strtoupper($row->valeur) == "AUTRE" || strtoupper($row->valeur) == "AUTRES") {
					$autreRow = $row;
				} else {
					$options[] = $row;
				}
			}
			if ($autreRow) {
				$options[] = $autreRow;
			}
		} elseif ($sourceListe == "user") {
			//on recup le critere d affichage dans champs_de_base
			$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql' => 'idUser'))->current();

			$codeType = '';
			if ($champOptions && substr($champOptions, 0, 8) == 'codeType') {
				$codeType = str_replace('codeType_', '', $champOptions);
			} elseif ($cb && $cb->critere) {
				$codeTypeArr = json_decode($cb->critere, true);
				if (!empty($codeTypeArr['codeType'])) {
					$codeType = $codeTypeArr['codeType'];
				}
			}
			if ($codeType) {
				$result = $this->getUserTable()->getUsersListeByCodeType($codeType, $idCampagne, $idResidenceUser);
				$usersDeleted = $this->getUserTable()->getUsersDeletedByCodeType($codeType, $idCampagne, $idResidenceUser);
				foreach ($result as $id => $val) {
					$r = new \stdClass();
					$r->id = $id;
					$r->valeur = $val;
					$r->deleted = 0;
					if (array_key_exists($id, $usersDeleted)) {
						//$r->deleted = 1;
						continue;
					}
					$options[] = $r;
				}
				$r = new \stdClass();
				$r->id = 0;
				$r->valeur = "Aucun";
				$options[] = $r;
			}
		} elseif ($sourceListe == "residences") {
			$rows =  $this->getResidencesTable()->fetchByGest($gestId);
			foreach ($rows as $row) {
				$r = new \stdClass();
				$r->id = $row->id;
				$r->valeur = $row->nom;
				$r->deleted = 0;
				$options[] = $r;
			}
		}

		return $options;
	}
	private function utf8_encode_deep(&$input)
	{
		if (is_string($input)) {
			$input = utf8_encode($input);
		} elseif (is_array($input)) {
			foreach ($input as &$value) {
				$this->utf8_encode_deep($value);
			}

			unset($value);
		} elseif (is_object($input)) {
			$vars = array_keys(get_object_vars($input));

			foreach ($vars as $var) {
				$this->utf8_encode_deep($input->$var);
			}
		}
	}

	private function encodeEnUtf8($array = array())
	{
		$return = array();
		foreach ($array as $keys => $values) {
			foreach ($values as $key => $value) {
				$value = iconv(mb_detect_encoding($value, mb_detect_order(), true), "UTF-8", $value);
				//$value = utf8_encode($value);
				$return[$keys][$key] = $value;
			}
		}
		return $return;
	}

	public function getApisignatureTable()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK :");
		if (!$this->apisignatureTable) {
			$sm = $this->getServiceLocator();
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : class_sm=".get_class($sm));
			$this->apisignatureTable = $sm->get('Reservation\Model\ApisignatureTable');
		}
		return $this->apisignatureTable;
	}

	public function getApisettingsignatureTable()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK :");
		if (!$this->apisettingsignatureTable) {
			$sm = $this->getServiceLocator();
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : class_sm=".get_class($sm));
			$this->apisettingsignatureTable = $sm->get('Reservation\Model\ApisettingsignatureTable');
		}
		return $this->apisettingsignatureTable;
	}

	private function getIntercontratByResa($idResa)
	{
		$table = $this->getTableObjet('intercontrat');
		$select = $table->getSql()->select();
		$select->join('user', 'user.user_id = intercontrat.userid', array('display_name'), 'LEFT');
		$select->join('etat_intercontrat', 'etat_intercontrat.id = intercontrat.idEtat', array('etat' => 'nom'), 'LEFT');
		$select->where(array('intercontrat.idReservation' => $idResa));
		$rows = $table->selectWith($select);
		return $rows;
	}

	private function getDynamiqueFields()
	{
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		$theme = array();
		foreach ($champsDynamiques as $row) {
			$obj = new \stdClass();
			$obj->code = $row->equivalentSql;
			$obj->id = $row->id;
			$obj->nom = $row->libelle;
			$theme[$obj->code] = $obj;
		}
		return $theme;
	}

	public function getListProfileAction()
	{
		$request = $this->getRequest();
		$profiles = [];
		if ($request->isXmlHttpRequest()) {
			$idListe = $request->getPost('idListe');
			$mode = $request->getPost('mode');

			$listeDp = null;
			$tableObj = new Tables('liste_profile', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
			if (!empty($mode)) {
				if ($mode == 'dp') {
					$tableObj = new Tables('domiciliations_liste_profile', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
					$listeDp = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				}
			}
			$select = $tableObj->getTable()->getSql()->select();
			$select->where(array('idListe' => $idListe));
			$rows = $tableObj->getTable()->selectWith($select);
			foreach ($rows as $row) {
				$profiles[] = $row->idProfile;
			}
		}
		$view = new JsonModel(array(
			'profiles'	=> $profiles,
			'listeDp' => $listeDp ? $listeDp : null,
		));
		$view->setTerminal(true);
		return $view;
	}

	public function getListeInfosAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId = $user->getId();
			$userCo = $this->getTableObjet('user')->select(array('user_id' => $gestId))->current();
			if ($userCo) {
				$profileCo = $this->getTableObjet('user_role_linker')->select(array('user_id' => $gestId))->current();
				$roleUserCo = $profileCo->role_id;
			}
		}

		if ($request->isXmlHttpRequest()) {
			$idListe = $request->getPost('idListe');
			$mode = $request->getPost('mode');

			$htmlOptions = ''; // HTML pour les options du select multiple profiles

			if ($mode == 'dp') {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				$profilesListe = $this->getTableObjet('domiciliations_liste_profile')->select(array('idListe' => $idListe))->toArray();
				$typeListe = $this->getTableObjet('type_domiciliations')->select(array('id' => $liste->idType))->current();
			} elseif ($mode == 'demandes') {
				$liste = $this->getTableObjet('demandes_listes')->select(array('id' => $idListe))->current();
				$profilesListe = $this->getTableObjet('demandes_liste_profile')->select(array('idListe' => $idListe))->toArray();
				$typeListe = $this->getTableObjet('demandes_type_liste')->select(array('id' => $liste->idTypeListe))->current();
			} elseif ($mode == 'suivis') {
				$liste = $this->getTableObjet('suivis_listes')->select(array('id' => $idListe))->current();
				$profilesListe = $this->getTableObjet('suivis_liste_profile')->select(array('idListe' => $idListe))->toArray();
				$typeListe = $this->getTableObjet('suivis_type_liste')->select(array('id' => $liste->idTypeListe))->current();
			} else {
				$liste = $this->getTableObjet('listes')->select(array('id' => $idListe))->current();
				$profilesListe = $this->getTableObjet('liste_profile')->select(array('idListe' => $idListe))->toArray();
				$typeListe = $this->getTableObjet('type_liste')->select(array('id' => $liste->idType))->current();
			}

			$typeL = $typeListe->type;

			$profilesAllowed = array();
			foreach ($profilesListe as $key => $profileListe) {
				$profile = $profileListe['idProfile'];
				$profilesAllowed[$profile] = $profileListe;
			}

			$allProfiles = $this->getTableObjet('user_role')->select();
			$allowedProfiles = array();
			if ($allProfiles) {
				foreach ($allProfiles as $row) {
					if ($row->role_id != 'guest' && $row->role_id != 'user') {
						$allowedProfiles[] = $row;
					}
				}
			}
			if ($allowedProfiles) {
				foreach ($allowedProfiles as $profile) {
					$role_id = $profile['role_id'];
					$role_name = $profile['role_name'];
					$htmlOptions .= '<option ';
					$htmlOptions .= 'value="'.$role_id.'"';
					if ($roleUserCo && $role_id == $roleUserCo) {
						$htmlOptions .= ' selected="selected"';
					} elseif (array_key_exists($role_id, $profilesAllowed)) {
						$htmlOptions .= ' selected="selected"';
					}
					$htmlOptions .= '>'.$role_name.'</option>';
				}
			}
		}
		$view = new JsonModel(array(
			'liste' => $liste,
			'typeL' => $typeL,
			'htmlOptions' => $htmlOptions,
		));
		$view->setTerminal(true);
		return $view;
	}

	public function loadmodepresentsAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] ");
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modepresents');

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOutput,
				'champModalHtml' => $this->loadChampsModal(),
			));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadPresentState()
	{
		$logeStateArr	= array();
		$logeStateObj	= $this->getTableObjet('presents_state')->select()->current();
		if ($logeStateObj) {
			$logeState	= json_decode($logeStateObj->data, 1);
			if ($logeState && array_key_exists('filter', $logeState)) {
				$logeStateArr	= $logeState;
			}
		}
		return	$logeStateArr;
	}

	public function savestatepresentAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonICDatatableState = $request->getPost('jsonICDatatableState', array());

			$ICStateObj	= $this->getTableObjet('presents_state')->select()->current();
			if ($ICStateObj) {
				$this->getTableObjet('presents_state')->update(array('data' => json_encode($jsonICDatatableState)));
			} else {
				$this->getTableObjet('presents_state')->insert(array('data' => json_encode($jsonICDatatableState)));
			}
			$view = new JsonModel(['success' => true]);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function affichepresentsAction()
	{
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonPresentDatatableState = $request->getPost('jsonPresentDatatableState', array());
			$jsonLogeDatatableFrom  = 'POST';
			if (empty($jsonPresentDatatableState)) {
				$jsonPresentDatatableState = $this->loadPresentState();
				$jsonLogeDatatableFrom  = 'BDD';
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] post=".json_encode($request->getPost()));

			$jsonPresentDatatableFilter = array_key_exists('filter', $jsonPresentDatatableState) ? $jsonPresentDatatableState['filter'] : [];

			// Valeurs uniques pour les différents selects
			$selectOptions	= array();

			// Constitution d'une liste des lignes
			$rowsAll = $listeChampsAffiches = array();

			if ($jsonPresentDatatableFilter) {
				// Initialisation de la liste des champs de logements
				$formFields     = $this->getResaFields(0, $jsonPresentDatatableFilter);

				// Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				$listeChampsAffiches    = $this->getlisteChampsAffiches($jsonPresentDatatableFilter, $formFields);

				// var_dump($listeChampsAffiches);die();

				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where = array();

				$rowsAll = $this->getResaTable()->getListeWithAllFields($adapter, 0, $listeChampsAffiches, $where, array('config' => $conf));

				// Constitution de la liste des options
				if ($rowsAll) {
					foreach ($rowsAll as $_key => $_row) {
						foreach ($_row as $_colName => $_value) {
							if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
								}
								$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
								if (!$_options || !in_array($_value, $_options)) {
									$selectOptions[$_colName][] = $_value;
								}
							} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($_value) {
									$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
									if(!empty($valsArr)) {
										foreach($valsArr as $k => $v) {
											$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
											if (!$_options || !in_array($v, $_options)) {
												$selectOptions[$_colName][] = $v;
											}
										}
									}
								}
							}
						}
					}
				}

				// Tri de ces options dans l'ordre alphabétique
				foreach ($selectOptions as $_colName => $_options) {
					sort($selectOptions[$_colName], SORT_STRING);
				}
			}

			$champsNonModifiables = array(
								'idReservation', 'idLocataire', 'idPMS',
								'nomLocataire', 'prenomLocataire', 'etatReservation',
								'campagne', 'programmeEcole', 'sousProgrammeEcole', 'programme', 'sousProgramme',
								'batiment', 'residence',
								'etatIntercontrat',
								'typeLogement1', 'typeLogement2', 'typeLogement3', 'typeLogement4', 'typeLogementAttribue', 'prelevementLoyer',
								'clesPrincipale',
							);

			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/afficherpresents')
				->setVariables(array(
					'rows' 		=> array(),
					'resaFields' 	=> isset($formFields) ? $formFields['resaFields'] : [],
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'				=> 1,
					'jsonICDatatableState' => $jsonPresentDatatableState,
					'selectOptions'	=> $selectOptions,
					'isPlanning' => 0,
					'champsNonModifiables'	=> $champsNonModifiables,
					'config' => $conf,
				));

			$htmlOutput = $this->getServiceLocator()
					->get('viewrenderer')
					->render($htmlViewPart);

			$view = new JsonModel(array(
					'success' => true,
					'champs' => $listeChampsAffiches,
					'htmlOP' => $htmlOutput,
					));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function searchpresentsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$startDate = date('Y-m-d', strtotime($request->getPost('startDate')));
			$endDate = date('Y-m-d', strtotime($request->getPost('endDate') ? $request->getPost('endDate') : '01-01-2038'));
			$tempChamps = $request->getPost('champs');
			$champs = [];
			if (is_array($tempChamps)) {
				foreach ($tempChamps as $row) {
					if ($row['name'] === 'idLst') {
						continue;
					}
					$champs[] = $row['value'];
				}
			}

			if (!$champs) {
				$champs = $this->loadpresents();
			}

			if (!$champs) {
				$champs = ['id', 'nomLocataire', 'prenomLocataire', 'emailLocataire', 'dateArrivee', 'dateDepart'];
			}

			$rows = $this->getResaTable()->getPresents($startDate, $endDate, $champs);
			$fields = $this->getChamps($champs);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/modepresentstable')
			->setVariables(array(
				'fields' => $fields,
				'rows' => $rows,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOutput,
			));
			$view->setTerminal(true);
			return $view;
		}
	}

	public function savepresentsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids1 = $request->getPost('champs1') ? $request->getPost('champs1') : [];
			$ids2 = $request->getPost('champs2') ? $request->getPost('champs2') : [];
			$ids3 = $request->getPost('champs3') ? $request->getPost('champs3') : [];
			$ids6 = $request->getPost('champs6') ? $request->getPost('champs6') : [];
			$champs = array_merge($ids1, $ids2, $ids3, $ids6);
			$row = $this->getTable('presents_save')->select()->current();
			if ($row) {
				$this->getTable('presents_save')->update(['champs' => json_encode($champs)]);
			} else {
				$this->getTable('presents_save')->insert(['champs' => json_encode($champs)]);
			}
			$view = new JsonModel(array(
				'success' => true,
			));
			$view->setTerminal(true);
			return $view;
		}
	}

	private function loadpresents()
	{
		$row = $this->getTable('presents_save')->select()->current();
		return $row ? json_decode($row->champs) : [];
	}

	private function getChamps($champs)
	{
		$tableObj = new Tables('champs', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));

		$select1 = $tableObj->getTable()->getSql()->select();
		//$select1->where(array('idTheme' => '1'));
		$select1->order(array('ordre ASC'));
		$theme1Result = $tableObj->getTable()->selectWith($select1);

		$fields = array();

		foreach ($theme1Result as $t1) {
			if (in_array($t1->code, $champs)) {
				$fields[$t1->code] = $t1;
			}
		}

		//On recupere les champs dynamique
		$champsDynamiques = $this->getChampsTable()->getAllChampDynamique();
		foreach ($champsDynamiques as $t1) {
			if (in_array($t1->equivalentSql, $champs)) {
				$obj = new \stdClass();
				$obj->code = $t1->equivalentSql;
				$obj->id = $t1->id;
				$obj->nom = $t1->libelle;
				$obj->idTypeHtml = $t1->idType;
				$fields[$obj->code] = $obj;
			}
		}

		return $fields;
	}

	public function getPeriodesTravaux($idLogement)
	{
		if (!$idLogement) {
			return array();
		}
		$rows = array();
		$resultSet = $this->getTableObjet('logements_periode_travaux')->select(array('idLogement' => $idLogement));
		foreach ($resultSet as $r) {
			$rows[] = $r;
		}
		return $rows;
	}

	## recup de la resa pour certain action de listes, genre checkout
	public function getresaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = (int) $request->getPost('idResa');

			$resa =  $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();

			$view = new JsonModel(array(
						'success' => true,
						'idResa' => $idResa,
						'resa' => $resa,

			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## recup de la resa pour certain action de listes, genre checkout
	public function getResaAndLocataireInfosAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idLocataire = (int) $request->getPost('idLocataire');
			$idResa = (int) $request->getPost('idResa');

			$resa =  $this->getTableObjet('reservations')->select(array('id' => (int) $idResa))->current();
			$locataire =  $this->getTableObjet('locataires')->select(array('id' => (int) $idLocataire))->current();

			$view = new JsonModel(array(
						'success' => true,
						'resa' => $resa,
						'locataire' => $locataire,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function envoisMailEchoueAction()
	{
		$i++;
		$idModele = 220;
		$table = $this->getTableObjet('reservations');
		$select = $table->getSql()->select();
		$select->where("etat IN(6,7) AND idGroupeResa IS NULL AND archive='0'");
		$rows = $table->selectWith($select);
		//$now = date('2018-04-12');
		foreach ($rows as $resa) {
			$dejaEnvoyer = $this->getTableObjet('historique_mail')->select(array('idModele' => $idModele, 'idLocataire' => $resa->idLocataire))->current();
			if (!$dejaEnvoyer) {
				$loc = $this->getTableObjet('locataires')->select(array('id' => $resa->idLocataire))->current();
				echo $loc->emailHec ? $loc->emailHec : $loc->email;
				echo " - IDLOC ".$loc->id." <br>";
				## envois de mail, à décommenter la ligne suivante pour activer l'envois
				//$this->envoyerMail($resa->id,0,$idModele);
				$i++;
			}
		}
		echo "$i mails";
		exit();
	}

	public function showResaAction()
	{
		$idResa = $this->params()->fromRoute('id', 0);
		$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
		print_r($resa);
		if ($resa) {
			$loc = $this->getTableObjet('locataires')->select(array('id' => $resa->idLocataire))->current();
			echo "<br><br>";
			print_r($loc);
			if ($resa->idLogement) {
				$loge = $this->getTableObjet('logements')->select(array('id' => $resa->idLogement))->current();
				echo "<br><br>";
				print_r($loge);
			}
		}
		exit();
	}

	public function showDpAction()
	{
		$idDp = $this->params()->fromRoute('id', 0);
		$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
		print_r($dp);
		if ($dp) {
			$loc = $this->getTableObjet('locataires')->select(array('id' => $dp->idLocataire))->current();
			echo "<br><br>";
			print_r($loc);
		}
		exit();
	}

	## ajout profiles modeles des email, puisque on a la table vide, on donne à tout les profil acces à tout les modeles
	public function majProfilesModelesEmailAction()
	{
		$modelesResult = $this->getTableObjet('modeles_email')->select(array('deleted' => '0'));
		$modelesIds = array();
		foreach ($modelesResult as $row) {
			$modelesIds[] = $row->id;
		}
		$profilesResult = $this->getTableObjet('user_role')->select();
		$i = 0;
		$rows = $this->getTableObjet('modeles_email_profile')->select();
		if ($rows->count() > 1) {
			echo "On a déjà des profil dans la table, il faut la vider pour affecter à tout le monde";
			exit();
		}
		foreach ($profilesResult as $profile) {
			if ($profile->role_id != "guest" && $profile->role_id != "user") {
				foreach ($modelesIds as $idModele) {
					$pRow = $this->getTableObjet('modeles_email_profile')->select(array('idProfile' => $profile->role_id, 'idModele' => $idModele))->current();
					if (!$pRow) {
						$this->getTableObjet('modeles_email_profile')->insert(array('idProfile' => $profile->role_id, 'idModele' => $idModele));
						$i++;
					}
				}
			}
		}
		echo "$i lignes ajouté";
		exit();
	}

	public function getListeTypesSuivis()
	{
		$types = array();
		$result = $this->getTableTypeSuivi()->select(array('deleted' => 0));
		foreach ($result as $row) {
			$types[$row->id] = $row->type;
		}

		// usort($types, function ($a, $b) {
		//     return strcmp($a, $b);
		// });

		return $types;
	}

	public function getTableTypeSuivi()
	{
		return $this->getTableObjet('type_suivi');
	}

	//rechargement de la liste des suivis apres validation
	public function loadtablesuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$idResa = $request->getPost('idResa', 0);
			$idDp = $request->getPost('idDp', 0);
			$idLocataire = $request->getPost('idLocataire', 0);
			$idTypeSuivis = $request->getPost('idTypeSuivis');
			$idLogement = $request->getPost('idLogement', 0);
			$idFormulaireCampagne = $request->getPost('idFormulaireCampagne', 0);
			$listeHtml = "";

			## Si le type_suivi est de type_suivi courriers, recharger le nb de courriers
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$typeSuivi = $this->getTableObjet('type_suivi')->select(array('id' => $idTypeSuivis))->current();
			if ($typeSuivi->type_suivi == 'courriers') {

				$sqlSuivis = "SELECT * FROM suivis LEFT JOIN domiciliations ON domiciliations.id = suivis.idDp WHERE domiciliations.idLocataire = ".$idLocataire;
				$rows = $adapter->query($sqlSuivis)->execute();
				$suivis = array();
				foreach ($rows as $row) {
					$suivis[] = $row;
				}

				$nbRemis = 0;
				$nbAremettre = 0;
				$nbRetourExp = 0;
				$nbNonRemis = 0;
				$nbCourriers = [];
				foreach ($suivis as $suivi) {
					if ($suivi['etatCourrier'] == 'Remis') {
						$nbRemis++;
					} elseif ($suivi['etatCourrier'] == 'A remettre') {
						$nbAremettre++;
					} elseif ($suivi['etatCourrier'] == 'Retour expéditeur') {
						$nbRetourExp++;
					} elseif ($suivi['etatCourrier'] == 'Non remis') {
						$nbNonRemis++;
					}
				}
				$nbCourriers['remis'] = $nbRemis;
				$nbCourriers['aRemettre'] = $nbAremettre;
				$nbCourriers['retourExp'] = $nbRetourExp;
				$nbCourriers['nonRemis'] = $nbNonRemis;

				$nbCourriersHtml = '<p style="margin-bottom: 1em">Nombre de courriers</p>
					<div id="courriersRemis" class="col-lg-12">Remis : '.$nbCourriers['remis'].'</div>
					<div id="courriersAremettre" class="col-lg-12">A remettre : '. $nbCourriers['aRemettre'].'</div>
					<div id="courriersAremettre" class="col-lg-12">Retour expéditeur : '. $nbCourriers['retourExp'].'</div>
					<div id="courriersAremettre" class="col-lg-12">Non remis : '. $nbCourriers['nonRemis'].'</div>';
			}
			
			if ($idResa || $idCampagne || $idDp || $idLogement) {
				//$resa = $this->getResaTable()->getResa($idResa);
				$listeHtml = $this->loadSuivisTab($idResa, $idTypeSuivis, array('typeRetour' => 'tableau',
																				'idDp' => $idDp,
																				'idLogement' => $idLogement,
																				'idFormulaireCampagne' => $idFormulaireCampagne,
																				));
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'listeHtml' => $listeHtml,
				'nbCourriersHtml' => $nbCourriersHtml,
				'codeTypeSuivi' => $typeSuivi->type_suivi,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//rest le formulaire des suivis pour un nouveau ajout
	public function resetsuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$idDp = $request->getPost('idDp');
			$idTypeSuivis = $request->getPost('idTypeSuivis');
			$formHtml = "";
			$msg = "Erreur chargement, veuillez re essayer.";
			$success = false;
			$msgClass = "danger";
			if ($idResa || $idDp) {
				//$resa = $this->getResaTable()->getResa($idResa);
				$return = $this->loadSuivisTab($idResa, $idTypeSuivis, array('typeRetour' => 'reset', 'idDp' => $idDp));
				$formHtml = $return['html'];
				$msg = "Veuillez remplir le formulaire et le valider";
				$success = true;
				$msgClass = "success";
			}

			$view = new JsonModel(array(
				'success'  => $success,
				'formHtml' => $formHtml,
				'msgClass' => $msgClass,
				'msg'	   => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## les logs par suivis, appeler quand on clique sur l affichage des logs dasn la list des suivis, onglet suivis de la fiche locataire
	public function getlogssuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idSuivis = $request->getPost('idSuivis');
			$htmlOP = "";
			$rows = array();
			$rows = $this->getTableObjet('suivis_historique')->select(array('idSuivis' => $idSuivis));

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/suivislogs')
			->setVariables(array(
				'rows' => $rows,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## fonction archive suivis
	public function archiversuivisAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$user = $auth->getIdentity();
		if ($request->isXmlHttpRequest()) {
			$idSuivis = $request->getPost('idSuivis');
			$idResa = $request->getPost('idResa');
			$msg = "";

			$ids = array();
			if ($idSuivis && !is_array($idSuivis)) {
				$ids[] = $idSuivis;
			} elseif (is_array($idSuivis)) {
				$ids = $idSuivis;
			}

			$success = false;
			$msgClass = "danger";
			foreach ($ids as $idSuivis) {
				if ($idSuivis) {
					$suivi = $this->getTableObjet('suivis')->select(array('id' => $idSuivis))->current();
					$this->getTableObjet('suivis')->update(array('deleted' => 1), array('id' => $idSuivis));

					if ($suivi) {
						$idResa = $suivi->idResa;
					}

					$msg .= "Suivi $idSuivis bien supprimé <br>";
					$success = true;
					$msgClass = "success";
					$comment = ('Suivis supprimé par "'.$user->getDisplayname().'"');
					$type = 'Suppression suivis';
					$this->getTableObjet('suivis_historique')->insert(array('idResa' => $idResa, 'type' => $type, 'commentaire' => $comment, 'idSuivis' => $idSuivis, 'idUser' => $user->getId()));
				}
			}
			if ($msg == "") {
				$msg = "Erreur suppression";
			}

			$view = new JsonModel(array(
				'success' 	=> $success,
				'msg'		=> $msg,
				'idSuivis' => $idSuivis,
				'msgClass' => $msgClass,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//appeler lors de l  edition de la suivis dans l onglet suivis de la fiche locataire
	public function editsuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idSuivis = $request->getPost('idSuivis');
			$idResa = $request->getPost('idResa');
			$idDp = $request->getPost('idDp');
			$idTypeSuivis = $request->getPost('idTypeSuivis');
			$formHtml = "";
			$msg = "Erreur chargement";
			if ($idSuivis && ($idResa || $idDp)) {
				// $resa = $this->getResaTable()->getResa($idResa);
				$returnForm = $this->loadSuivisTab($idResa, $idTypeSuivis, array('idSuivis' => $idSuivis, 'idDp' => $idDp));
				$formHtml = $returnForm['html'];
				$champsDoc = !empty($returnForm['champsDoc']) ? $returnForm['champsDoc'] : array();
				$msg = "Infos bien chargé";
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'msg'		=> $msg,
				'formHtml' => $formHtml,
				'idSuivis' => $idSuivis,
				'champsDoc' => $champsDoc,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function typesuiviAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$data = $request->getPost();
			$insertionValeurParDefaut = $request->getPost('insertionValeurParDefaut');

			if (!empty($data['insertionValeurParDefaut']) && $data['insertionValeurParDefaut'] == '1') {
				$idTypeSuivis = $data['idTypeSuivis'];

				// récuperation des champs appartenant au suivi
				$champs = $this->getTableObjet('champs_suivis')->select(array('idTypeSuivis' => $idTypeSuivis));
				foreach ($champs as $champ) {
					if ($champ->idTypeSuivis == $idTypeSuivis) {
						$this->getTableObjet('champs_suivis')->update(
							array('valeurParDefaut' => $data[$champ->name]),
							array('idTypeSuivis' => $idTypeSuivis, 'name' => $champ->name)
						);
					}
				}

				return new JsonModel(array('succeed' => true));
			} else {
				$id = $request->getPost('idTypeSuivi');

				// Récuperation de tous les champs appartenant au mutlisuivis
				$fields = $this->getChampsTypeSuivis($id);

				$return = $this->buildSuivisForm('', $fields, array(), $id);//return array html, validator

				return new JsonModel(array('forms' => $forms['html']));
			}
		}
	}

	public function loadFormSuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idSuivis = $request->getPost('idSuivis', 0);
			$idTypeSuivis = $request->getPost('idTypeSuivis');
			$idResa = $request->getPost('idResa', 0);
			$idDp = $request->getPost('idDp', 0);
			$valider = $request->getPost('valider', '1');
			$disabled = $valider ? false : true;
			$idsResas = $request->getPost('ids', '');
			$mode = $request->getPost('mode', '');
			$idLogement = $request->getPost('idLogement', 0);
			$idFormulaireCampagne = $request->getPost('idFormulaireCampagne', 0);
			$htmlOP = "";

			$locataire = null;
			$idLocataire = 0;
			$typeSuivi = $this->getTableObjet('type_suivi')->select(array('id' => $idTypeSuivis))->current();

			if ($idDp) {
				$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
				$idLocataire = $dp->idLocataire; 
			}

			if ($idResa) {
				$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
				$idLocataire = $resa->idLocataire; 
			}

			if ($typeSuivi && $typeSuivi->type_suivi == 'courriers' && $idResa && !$idDp) {
				$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
				$campagnePourResa = $this->getTableObjet('campagnes')->select(array('utiliserDpPourResa' => '1', 'archive' => '0'))->current();
				$dpPourResa = $this->getTableObjet('domiciliations')->select(array('idLocataire' => $resa->idLocataire, 'idCampagne' => $campagnePourResa->id, 'etat' => '1'))->current();

				if (!$dpPourResa) {
					$view = new JsonModel(array(
						'success' 	=> false,
						'locataire' => $locataire,
						'typeSuivi' => $typeSuivi,
						'msg' => 'Aucune DP active. Veuillez ajouter une DP.'
					));

					$view->setTerminal(true);
					return $view;
				}
			}

			$suivis = $this->getTableObjet('suivis')->select(array('id' => $idSuivis))->current();
			$etatCourrier = $suivis->etatCourrier;
			if ($suivis && !$idDp) {
				$idDp = $suivis->idDp;
				$reservations = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
				$locataire = $this->getTableObjet('locataires')->select(array('id' => $reservations->idLocataire))->current();
				$idLocataire = $locataire->id; 
			}

			if ($suivis && !$idResa) {
				$idResa = $suivis->idResa;
				$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
				$locataire = $this->getTableObjet('locataires')->select(array('id' => $dp->idLocataire))->current();
				$idLocataire = $locataire->id; 
			}

			if ($suivis && !$idLogement) {
				$idLogement = $suivis->idLogement;
			}

			$returnForm = $this->loadSuivisTab($idResa, $idTypeSuivis, array('typeRetour' => 'reset', 'idDp' => $idDp, 'idSuivis' => $idSuivis, 'disabled' => $disabled, 'idLogement' => $idLogement, 'idFormulaireCampagne' => $idFormulaireCampagne));
			$form = $returnForm['html'];
			$champsDoc = !empty($returnForm['champsDoc']) ? $returnForm['champsDoc'] : array();

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/suivisform')
			->setVariables(array(
				'form' => $form,
				'idTypeSuivis' => $idTypeSuivis,
				'idResa' => $idResa,
				'idLocataire' => $idLocataire,
				'idSuivis' => $idSuivis,
				'etatCourrier' => $etatCourrier,
				'valider' => !$disabled,
				'clear' => !$disabled,
				'idsResas' => !empty($idsResas) ? implode('-', $idsResas) : '',
				'idDp' => $idDp,
				'mode' => $mode,
				'champsDoc' => $champsDoc,
				'idLogement' => $idLogement,
				'typeSuivi' => $typeSuivi,
				'idFormulaireCampagne' => $idFormulaireCampagne,
				'from' => !empty($idsResas) ? 'liste' : 'ficheUsager',
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
				'locataire' => $locataire,
				'typeSuivi' => $typeSuivi,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## action formawrder depuis LogementController pour recup des multisuivis
	public function loadLogementsSuivisTabsAction()
	{
		$idLogement = (int) $this->params()->fromRoute('id', 0);
		$typesSuivis = $this->getGlobalHelper()->getListeTypesSuivis('logements');
		$ongletsParTypeSuivis = array();
		foreach ($typesSuivis as $id => $type) {
			$ongletsParTypeSuivis[$id] = $this->loadSuivisTab(0, $id, array('idLogement' => $idLogement, 'from' => 'ficheLogement'));
		}

		return $ongletsParTypeSuivis;
		exit();
	}

	private function loadSuivisTab($idResa, $idTypeSuivis, $params = array())
	{
		$idSuivis = !empty($params['idSuivis']) ? $params['idSuivis'] : null;
		$idDp = !empty($params['idDp']) ? $params['idDp'] : null;
		$idLogement = !empty($params['idLogement']) ? $params['idLogement'] : null;
		$idFormulaireCampagne = !empty($params['idFormulaireCampagne']) ? $params['idFormulaireCampagne'] : null;
		$from = !empty($params['from']) ? $params['from'] : '';
		$idLocataire = 0;
		$idCampagne = 0;
		if ($idResa) {
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if ($resa) {
				$idLocataire = $resa->idLocataire;
				$idCampagne = $resa->idCampagne;
			}
		} elseif ($idDp) {
			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
			if ($dp) {
				$idLocataire = $dp->idLocataire;
				$idCampagne = $dp->idCampagne;
			}
		}

		$typeSuivi = $this->getTableObjet('type_suivi')->select(array('id' => $idTypeSuivis))->current();

		$modeCamp = null;
		if($idCampagne) {
			$modeCamp = $this->getCampagneTable()->getCampagneMode($idCampagne);
		}

		//$idDp = null;
		$disabled = !empty($params['disabled']) ? $params['disabled'] : false;
		$typeRetour = !empty($params['typeRetour']) ? $params['typeRetour'] : "";
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=".$idResa." idSuivis=$idSuivis");

		$data = array();
		$table = $this->getTableObjet('champs_suivis');
		$select = $table->getSql()->select();
		$select->join('suivis_values', 'suivis_values.idChamp = champs_suivis.id', array('dv_id' => 'id', 'dv_valeur' => 'valeur', 'dv_idSuivis' => 'idSuivis'));
		$select->join('valeurs_select', 'valeurs_select.idSelect = champs_suivis.sourceListe AND valeurs_select.id = suivis_values.valeur', array('vs_valeur' => 'valeur'), 'LEFT');
		$select->join('catalogue_suivis', 'suivis_values.idSuivis=catalogue_suivis.idSuivis', array('idCatalogue'), 'LEFT');
		$select->where(array('champs_suivis.idTypeSuivis' => $idTypeSuivis));

		if ($idSuivis) {
			$select->where(array('suivis_values.idSuivis' => $idSuivis));
		} else {
			if ($idLocataire) {
				if ($idDp) {
					$select->join('domiciliations', 'domiciliations.id = suivis_values.idDp', array('id_dp' => 'id', 'idLocataire'), 'LEFT');
					$select->where(array('domiciliations.idLocataire' => $idLocataire));
				} else {
					## Si le type_suivi est de type_suivi courriers et qu'on est sur une résa, chercher par la DP
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($typeSuivi && $typeSuivi->type_suivi == 'courriers') {
						$select->join('domiciliations', 'domiciliations.id = suivis_values.idDp', array('id_dp' => 'id', 'idLocataire'), 'LEFT');
						$select->where(array('domiciliations.idLocataire' => $idLocataire));
					} else {
						$select->join('reservations', 'reservations.id = suivis_values.idResa', array('id_resa' => 'id', 'idLocataire'), 'LEFT');
						$select->where(array('reservations.idLocataire' => $idLocataire));
					}
				}
			} else {
				if ($idDp) {
					$select->where(array('suivis_values.idDp' => $idDp));
				} elseif ($idLogement) {
					if($from == 'ficheLogement' || $idLogement) {
						$select->join('logements', 'logements.id = suivis_values.idLogement', array('idLoge' => 'id', 'numeroLogement' => 'numero'), 'LEFT');
						// on affiche les suivis des sous logements aussi
						$sousLogements = $this->getLogementTable()->getSousLogements($idLogement);
						if(!empty($sousLogements)) {
							$ids = array_keys($sousLogements);
							$ids[] = $idLogement;
							$select->where->in('suivis_values.idLogement', $ids);
						} else {
							$select->where(array('suivis_values.idLogement' => $idLogement));
						}
					} else {
						$select->where(array('suivis_values.idLogement' => $idLogement));
					}
				} else {
					$select->where(array('suivis_values.idResa' => $idResa));
				}
			}
		}

		$dvs = $table->selectWith($select);

		/*$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql'=>'idUser'))->current();
		$users = array();
		if($cb && $cb->critere){
			$codeTypeArr = json_decode($cb->critere,true);
			if(!empty($codeTypeArr['codeType'])){
				$users = $this->getUserTable()->getUsersListeByCodeType($codeTypeArr['codeType']);
			}
		}*/
		$users =  $this->getUserTable()->getUsersListe();

		$dataListe = array();//valeur par suivis
		foreach ($dvs as $dv) {
			$val = $dv->dv_valeur;
			$data[$dv->id] = $val;
			$dataListe[$dv->dv_idSuivis][$dv->id] = $dv->vs_valeur ? $dv->vs_valeur : $dv->dv_valeur;
			if (($dv->equivalentSql == 'idUser' || $dv->sourceListe == 'user')) {
				if($dv->idType == 18) {
					if($val) {
						$valsArr = explode(',', $val);
						$valsLib = array();
						foreach($valsArr as $v) {
							if(!empty($users[$v])) {
								$valsLib[] = $users[$v];
							}
						}
						if(!empty($valsLib)) {
							$val = implode(',', $valsLib);
						}
					}
				} elseif(!empty($users[$val])) {
					$val = $users[$val];
				}
				$dataListe[$dv->dv_idSuivis][$dv->id] = $val;
			} elseif ($dv->idType == 18) {
				if($val) {
					$valsArr = explode(',', $val);
					$valsLib = array();
					foreach($valsArr as $v) {
						$valSelect = $this->getTableObjet('valeurs_select')->select(array('id' => $v))->current();
						if($valSelect) {
							$valsLib[] = $valSelect->valeur;
						}
					}
					if(!empty($valsLib)) {
						$val = implode(', ', $valsLib);
					}
				}
				$dataListe[$dv->dv_idSuivis][$dv->id] = $val;
			}
		}

		//$fieldsResult = $this->getTableObjet('champs_suivis')->select(array('idTypeSuivis'=>$idTypeSuivis));
		$fields = $this->getChampsTypeSuivis($idTypeSuivis);
		if ($idSuivis) {
			foreach ($fields as $field) {
				if (strpos($field->equivalentSql, 'catalogues_') !== false) {
					$idTypeCatalogue = str_replace('catalogues_', '', $field->equivalentSql);
					$idCatalogue = $this->getCatalogueTable()->getCatalogueDeSuivisByTypeCatalogue($idSuivis, $idTypeCatalogue);
					$data[$field->id] = $idCatalogue;
					$dataListe[$idSuivis][$field->id] = $idCatalogue;
				}
			}
		}

		$select = $table->getSql()->select();
		$select->where(array('idTypeSuivis' => $idTypeSuivis));
		$select->where("(numOrdre > 0 OR champDeTri = '1' )");
		$select->order('numOrdre');

		$fieldsResult = $table->selectWith($select);
		$fieldsListe = array();
		foreach ($fieldsResult as $f) {
			$fieldsListe[] = $f;
		}
		//si la liste est vide, on prend le premier champs ajouté
		if (empty($fieldsListe)) {
			$fieldsListe[] = $fields[0];
		}


		if (($typeRetour == "reset" && !$idSuivis) || $typeRetour == "default") {
			//on vide le formulaire pour un nouveau ajout, ou quand on charge la fiche locataire pour la premier fois
			$data = array();
		}

		// var_dump($fields);die();

		$returnForm = $this->buildSuivisForm($idResa, $fields, $data, $idTypeSuivis, $idDp, $disabled, $idSuivis, $idLogement, array('idFormulaireCampagne' => $idFormulaireCampagne));//return array html, validator
		// var_dump($returnForm);die();

		$form = $returnForm['html'];
		$validator = !empty($returnForm['validator']) ? $returnForm['validator'] : array();

		//cas edition de la ligne suivis du tableau listesuivis, ou ajout d un nouveau suivis
		if ($idSuivis || $typeRetour == "reset") {
			//return array('form'=>$form,'validator'=>$validator);
			return $returnForm;
		}

		$tableSuivis = $this->getTableObjet('suivis');
		$select = $tableSuivis->getSql()->select();
		$select->where(array('suivis.deleted' => 0, 'suivis.idTypeSuivis' => $idTypeSuivis));
		if ($idLocataire) {
			if ($idDp) {
				$select->join('domiciliations', 'domiciliations.id = suivis.idDp', array('id_dp' => 'id', 'idLocataire'), 'LEFT');
				$select->where(array('domiciliations.idLocataire' => $idLocataire/*,'suivis.idDp'=>$idDp*/));
				if(!$modeCamp || $modeCamp->afficherSuivisParIdLocataire != '1' && $typeSuivi->type_suivi != 'courriers') {
					$select->where(array('suivis.idDp' => $idDp));
				}
			} elseif ($idResa) {
				## Si le type_suivi est de type_suivi courriers, chercher les suivis des DP liées au locataire sans faire attention au paramètre afficherSuivisParIdLocataire
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($typeSuivi && $typeSuivi->type_suivi == 'courriers') {
					$select->join('domiciliations', 'domiciliations.id = suivis.idDp', array('id_dp' => 'id', 'idLocataire'), 'LEFT');
					$select->where(array('domiciliations.idLocataire' => $idLocataire));	
				} else {
					$idsResa = array($idResa);
					//if ($resa->idAncienneResa) {
						//$idsResa[] = $resa->idAncienneResa;
					//}
					//if ($resa->idNouvelleResa) {
						//$idsResa[] = $resa->idNouvelleResa;
					//}
					if($resa->idAncienneResa || $resa->idNouvelleResa){
						$allIdsResa = $this->getResaTable()->getAllChangedResa($idResa);
						if(!empty($allIdsResa)){
							$idsResa = array_merge($allIdsResa,$idsResa);
						}
					}
					$select->join('reservations', 'reservations.id = suivis.idResa', array('id_resa' => 'id', 'idLocataire'), 'LEFT');
					$select->where(array('reservations.idLocataire' => $idLocataire));
					if(!$modeCamp || $modeCamp->afficherSuivisParIdLocataire != '1') {
						$select->where->in('suivis.idResa', $idsResa);
					}
				}
			} else {
				$select->join('reservations', 'reservations.id = suivis.idResa', array('id_resa' => 'id', 'idLocataire'), 'LEFT');
				$select->where(array('reservations.idLocataire' => $idLocataire));
			}
		} else {
			if (!empty($idDp)) {
				$select->where(array('idDp' => $idDp));
			} elseif ($idLogement) {
				if($from == 'ficheLogement' || $idLogement) {
					$select->join('logements', 'logements.id = suivis.idLogement', array('idLoge' => 'id', 'numeroLogement' => 'numero'), 'LEFT');
					// on affiche les suivis des sous logements aussi
					$sousLogements = $this->getLogementTable()->getSousLogements($idLogement);
					if(!empty($sousLogements)) {
						$ids = array_keys($sousLogements);
						$ids[] = $idLogement;
						$select->where->in('idLogement', $ids);
					} else {
						$select->where(array('idLogement' => $idLogement));
					}
				} else {
					$select->where(array('idLogement' => $idLogement));
				}
			} else {
				$select->where(array('idResa' => $idResa));
			}
		}
		$select->join('user', "user.user_id = suivis.idCreateurSuivis", array('createurSuivis' => 'display_name'), 'LEFT');
		//$select->join(	'catalogue_suivis', 'suivis.id=catalogue_suivis.idSuivis', array( 'idCatalogue'), 'LEFT');
		$select->order(array('dateCreationSuivis DESC', 'heureCreationSuivis DESC', 'id DESC'));
		$suivisResult = $tableSuivis->selectWith($select);
		//echo $suivisResult->count();exit();
		$champDeTri = $this->getTableObjet('champs_suivis')->select(array('champDeTri' => 1, 'idTypeSuivis' => $idTypeSuivis))->current();


		$financierData = array();//remonte champs financier
		$resaLocData = array();//remonte champs reservations/locataires
		$champsFinancier = $this->getFinancierTable()->getChampsFinancier();
		if ($idResa) {
			$financier = $this->getFinancierTable()->getFinancierDeResa($idResa);
			if ($financier) {
				if (!is_array($financier)) {
					$financierData = get_object_vars($financier);
				} else {
					$financierData = $financier;
				}
			}
			$resaLocData = array();
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if($resa) {
				$resaLocData = get_object_vars($resa);
				$loc = $this->getTableObjet('locataires')->select(array('id' => $resa->idLocataire))->current();
				if($loc) {
					$locArr = get_object_vars($loc);
					$resaLocData = array_merge($resaLocData, $locArr);
				}
			}

		}
		$suivis = array();
		foreach ($suivisResult as $s) {
			//if($s->idCatalogue){
			foreach ($fieldsListe as $field) {
				if (strpos($field->equivalentSql, 'catalogues_') !== false) {
					$idTypeCatalogue = str_replace('catalogues_', '', $field->equivalentSql);
					$idCatalogue = $this->getCatalogueTable()->getCatalogueDeSuivisByTypeCatalogue($s->id, $idTypeCatalogue);

					$catOption = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue, array(), $all = true);
					$dataListe[$s->id][$field->id] = !empty($catOption[$idCatalogue]) ? $catOption[$idCatalogue] : $idCatalogue;
				} elseif($field->nature == 'standard') {
					if (is_array($champsFinancier) && array_key_exists($field->equivalentSql, $champsFinancier)) {
						$dataListe[$s->id][$field->id] = $financierData[$field->equivalentSql];
					}
					if (is_array($resaLocData) && array_key_exists($field->equivalentSql, $resaLocData)) {
						$dataListe[$s->id][$field->id] = $resaLocData[$field->equivalentSql];
						if($field->sourceListe && !is_numeric($field->sourceListe)) {
							$rowVal = $this->getSelectValue($field, $resaLocData[$field->equivalentSql]);
							if($rowVal) {
								$dataListe[$s->id][$field->id] = $rowVal;
							}
						}
					}
				}
			}
			//}
			$suivis[] = $s;
		}

		//print_r($suivis);exit();

		// compter nb de courriers remis et a remettre
		// code type suivi
		$typeSuivi = $this->getTableObjet('type_suivi')->select(array('id' => $idTypeSuivis))->current();
		$codeTypeSuivi = $typeSuivi->type_suivi;
		if ($codeTypeSuivi == 'courriers') {
			$nbRemis = 0;
			$nbAremettre = 0;
			$nbRetourExp = 0;
			$nbNonRemis = 0;
			$nbCourriers = [];
			foreach ($suivis as $suivi) {
				if ($suivi['etatCourrier'] == 'Remis') {
					$nbRemis++;
				} elseif ($suivi['etatCourrier'] == 'A remettre') {
					$nbAremettre++;
				} elseif ($suivi['etatCourrier'] == 'Retour expéditeur') {
					$nbRetourExp++;
				} elseif ($suivi['etatCourrier'] == 'Non remis') {
					$nbNonRemis++;
				}
			}
			$nbCourriers['remis'] = $nbRemis;
			$nbCourriers['aRemettre'] = $nbAremettre;
			$nbCourriers['retourExp'] = $nbRetourExp;
			$nbCourriers['nonRemis'] = $nbNonRemis;
		}

		$where = array('active' => 1, 'imprimableEnLot' => 1, 'typeModele' => 'suivis');
		$modelesSuivis = $this->getTableObjet('type_modeles_docs')->select($where);

		//listes des suivis
		$htmlViewLC = new ViewModel();
		$htmlViewLC->setTerminal(true)
		->setTemplate('reservation/liste/suivisliste')
		->setVariables(array(
			"fields" => $fieldsListe,
			"data" => $dataListe,
			"suivis" => $suivis,
			"idTypeSuivis" => $idTypeSuivis,
			"idDp" => $idDp,
			"idResa" => $idResa,
			"idLocataire" => $idLocataire,
			"idLogement" => $idLogement,
			"typeSuivi" => $typeSuivi,
			"idFormulaireCampagne" => $idFormulaireCampagne,
			"editionDoc" => ($modelesSuivis->count() > 0 && ($_SESSION['USERDROIT']['liste-btn-modeles-docs-suivis'] == 'W' || $_SESSION['USERDROIT']['liste-btn-modeles-docs-suivis'] == 'R')) ? true : false,
			"champDeTri" => $champDeTri,
			"from" => $from,
		));
		$htmlLC = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewLC);

		if ($typeRetour == "tableau") {
			return $htmlLC;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/suivisTab')
		->setVariables(array(
			"form" => $form,
			"htmlLC" => $htmlLC,
			'idResa' => $idResa,
			"validator" => json_encode($validator, JSON_FORCE_OBJECT),
			"idTypeSuivis" => $idTypeSuivis,
			"idDp" => $idDp,
			"idLogement" => $idLogement,
			"nbCourriers" => $nbCourriers,
			"codeTypeSuivi" => $codeTypeSuivi,
			"idFormulaireCampagne" => $idFormulaireCampagne,
			"from"=>$from,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	private function getSelectValue($champ, $valeur)
	{
		$valSelect = null;
		if($champ->sourceListe) {
			if(is_numeric($champ->sourceListe)) {
				$rowVal = $this->getTableObjet('select_values')->select(array('id' => $valeur))->current();
				if($rowVal) {
					$valSelect = $rowVal->valeur;
				}
			} else {
				$rowVal = $this->getTableObjet($champ->sourceListe)->select(array('id' => $valeur))->current();
				if($rowVal) {
					if ($champ->equivalentSql == 'idPays') {
						$valSelect = $rowVal->pays;
					} elseif ($champ->equivalentSql == 'idNationalite') {
						$valSelect = $rowVal->nationalite;
					} elseif ($champ->sourceListe == 'pays') {
						$valSelect = $rowVal->pays;
					} else {
						$valSelect = $rowVal->nom;
					}
				}
			}
		}
		return $valSelect;
	}


	private function getChampsTypeSuivis($idTypeSuivis)
	{
		$fields = array();
		$tableChamps =  $this->getTableObjet('champs_suivis');
		$select = $tableChamps->getSql()->select();
		$select->where(array('idTypeSuivis' => $idTypeSuivis));
		$select->order(array('row', 'column'));
		$fieldsResult = $tableChamps->selectWith($select);
		$fields = array();
		foreach ($fieldsResult as $f) {
			$fields[] = $f;
		}
		return $fields;
	}

	private function getChampsSuivisLierAuActions($source = 'suivis')
	{
		$toutLesActionsResult = $this->getTable("actions_js_suivis")->select();
		$idsChampsActions = array();
		foreach ($toutLesActionsResult as $ra) {
			if ($source == 'campagne') {
				if (($ra->sourceChamp == 'champs_formulaires') && !in_array($ra->idChampAttache, $idsChampsActions)) {
					$idsChampsActions[$ra->idChampAttache] = $ra->idChamp;
				}
			} else {
				if (($ra->sourceChamp == 'champs_suivis' || !$ra->sourceChamp) && !in_array($ra->idChamp, $idsChampsActions)) {
					$idsChampsActions[] = $ra->idChamp;
				}
			}
			/*if(!in_array($ra->idChampAttache,$idsChampsActions)){
				$idsChampsActions[] = $ra->idChampAttache;
			}*/
		}
		return $idsChampsActions;
	}

	public function buildSuivisForm($idResa, $champs, $result, $idTypeSuivis = 0, $idDp = '', $disabled = false, $idSuivis = 0, $idLogement = '', $params = array())
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$numLigne = 0;
		$html = null;
		$columns = array();
		$tools = new Tools();
		$idFormulaireCampagne = !empty($params['idFormulaireCampagne']) ? $params['idFormulaireCampagne'] : null;

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$conf = $this->getConfigurationTable()->getConfig(1);

		$validator['locale'] = 'fr_FR';
		$validator['fields'] = array();
		$validator['submitButtons'] = '#suivis-submit'.$idTypeSuivis;

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();

		foreach ($champs as $champ) {
			if ($champ->column == 1) {
				$columns[$champ->row][1] = 4 * $champ->tailleColumn;
			} elseif ($champ->column == 2) {
				$columns[$champ->row][2] = 4 * $champ->tailleColumn;
			} elseif ($champ->column == 3) {
				$columns[$champ->row][3] = 4 * $champ->tailleColumn;
			}
		}

		if($idSuivis && $idLogement) {
			//cas sous logements : on prend le idLogement lié au suivis
			$suivisRow = $this->getTableObjet('suivis')->select(array('id' => $idSuivis))->current();
			if($suivisRow && $suivisRow->idLogement && $suivisRow->idLogement != $idLogement) {
				$idLogement = $suivisRow->idLogement;
			}
		}

		//print_r($result);exit();

		$idLocataire = "";
		$idCampagne = "";
		$financierData = array();
		$resaLocData = array();
		$champsFinancier = $this->getFinancierTable()->getChampsFinancier();
		if ($idResa) {
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if ($resa) {
				$idLocataire = $resa->idLocataire;
				$idCampagne = $resa->idCampagne;
				//remonte champs financier
				$financier = $this->getFinancierTable()->getFinancierDeResa($idResa);
				if ($financier) {
					if (!is_array($financier)) {
						$financierData = get_object_vars($financier);
					} else {
						$financierData = $financier;
					}
				}
				//remonte des infos résa
				$resaLocData = get_object_vars($resa);
			}

		} elseif ($idDp) {
			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
			if ($dp) {
				$idLocataire = $dp->idLocataire;
				$idCampagne = $dp->idCampagne;
			}
		}
		if($idLocataire) {
			$loc = $this->getTableObjet('locataires')->select(array('id' => $idLocataire))->current();
			if($loc) {
				$locArr = get_object_vars($loc);
				$resaLocData = array_merge($resaLocData, $locArr);
			}
		}

		$tableSuivisVals = $this->getTableObjet('suivis_values');

		$champsFormule = $this->getFormuleExcelTable()->fetchAllByKey($idTypeSuivis);

		$idsChampsActions = $this->getChampsSuivisLierAuActions();//on y stock tout les champs lier au action pour ne verifier que ceux la
		$idsChampsCampagneActions = $this->getChampsSuivisLierAuActions('campagne');//key : idChampAttache(champs suivis), val:idChamp(champs campagne)
		$champsDoc = array();
		$ii = 0;
		foreach ($champs as $champ) {
			if ($champ->active == 0) {
				continue;
			}

			if($champ->nature == 'standard') {
				## remonte des infos financier
				if (!empty($financierData)  && !empty($financierData[$champ->equivalentSql])) {
					$result[$champ->id] = $financierData[$champ->equivalentSql];
				}
				## remonte des infos reservations/locataires
				if (!empty($resaLocData)  && !empty($resaLocData[$champ->equivalentSql])) {
					$result[$champ->id] = $resaLocData[$champ->equivalentSql];
				}
			}
			//calcule formule excel
			if ($champ->idType == 21) {
				//Formule excel prestation
				//if(empty($result[$champ->id])){
				$champ->modifiable = 0;//on le rend non modifiable
				$oldVal = !empty($result[$champ->id]) ? $result[$champ->id] : '';
				$dataFormule = array();
				foreach ($result as $k => $v) {
					$dataFormule['champs_suivis|'.$k] = $v;
				}

				$val = $this->getFormuleExcelTable()->calculerFormule($champ->formule, $idTypeSuivis, $idResa, $idDp, $dataFormule, $adapter);

				if ($val || $val == 0) {
					$result[$champ->id] = $val;
					//si la valeur est différente on maj le resultat
					if ($val != $oldVal && $idSuivis > 0) {
						//on regarde si c'est pas deja facture
						$p2s = $this->getFormuleExcelTable()->getPrestationToSuivisBy(array('idSuivis' => $idSuivis, 'idChamp' => $champ->id));

						if (!$p2s) {
							$suivisRow = $tableSuivisVals->select(array('idSuivis' => $idSuivis, 'idChamp' => $champ->id))->current();
							if ($suivisRow) {
								$tableSuivisVals->update(array('valeur' => $val), array('id' => $suivisRow->id));
							} else {
								$suivisData = array('idSuivis' => $idSuivis, 'idChamp' => $champ->id, 'valeur' => $val);
								if ($idResa) {
									$suivisData['idResa'] = $idResa;
								}
								if ($idDp) {
									$suivisData['idDp'] = $idDp;
								}
								if ($idLogement) {
									$suivisData['idLogement'] = $idLogement;
								}
								$tableSuivisVals->insert($suivisData);
							}
						}
					}
				}
				if($idSuivis) {
					$pRow = $this->getFormuleExcelTable()->getEtatPrestationDeSuivis(array('idSuivis' => $idSuivis, 'idChamp' => $champ->id));
					if($pRow && $pRow->etatPrestation) {
						$etatPrest = $pRow->etatPrestation;
						if($etatPrest == 'preparationFacture') {
							$etatPrest = "Préparation facture";
						} elseif($etatPrest == 'facture') {
							$etatPrest = "Facturé";
						} elseif($etatPrest == 'regle') {
							$etatPrest = "Reglé";
						}
						$champ->libelle .= " ($etatPrest)";
					}
				}
				//}
			}

			$extraOption = null;
			$validator['fields'][$champ->equivalentSql]['validators'] = array();
			if ($champ->obligatoire) {
				$extraOption .= ' required ';
			}

			if ($champ->obligatoire) {
				$extraOption .= ' required ';
				$validator['fields'][$champ->equivalentSql]['validators']['notEmpty'] = array();
			}

			if (is_array($champsFinancier) && $champ->nature == 'standard' && array_key_exists($champ->equivalentSql, $champsFinancier)) {
				$extraOption .= ' readonly="readonly" ';
			}

			$extraOption .= ' data-idchamp="'.$champ->id.'" ';
			$extraOption .= ' data-css="'.htmlspecialchars($champ->styleCss, ENT_QUOTES, 'UTF-8').'" ';
			$extraOption .= ' data-row="'.$champ->row.'" ';

			// si le champ appartient dans la liste des champs qui possede une formule prestation
			if (array_key_exists('champs_suivis|'.$champ->id, $champsFormule)) {
				$extraOption .= ' data-possedeformule="true" ';
			} else {
				$extraOption .= ' data-possedeformule="false" ';
			}

			if (!$champ->modifiable || $disabled) {
				if ($champ->idType == 3 || $champ->idType == 18) {
					$extraOption .= ' disabled="disabled" readonly="readonly" ';
				} else {
					$extraOption .= ' readonly="readonly" ';
				}
			}

			if ($champ->idType == 3 || $champ->idType == 18) {
				$extraOption .= ' data-sourceliste="'.$champ->sourceListe.'" ';
			}

			// on cherche le champ existe dans la table actions_js_suivis
			$actions_js_suivis = $this->getTableObjet('actions_js_suivis')
			->select(array('idChampAttache' => $champ->id,'idType'=>1))->current();
			if ($actions_js_suivis) {
				$extraOption .= ' data-hide="1"';
			} else {
				$extraOption .= ' data-hide="0"';
			}

			if (in_array($champ->id, $idsChampsActions)) {
				$extraOption .= ' data-action="1"';
			}
			if (array_key_exists($champ->id, $idsChampsCampagneActions)) {
				$extraOption .= ' data-action="1" data-idchampcampagne="'.$idsChampsCampagneActions[$champ->id].'" ';
			}

			if ($champ->idType == "5" || $champ->idType == "12" || $champ->idType == "2" || $champ->idType == "19") {
				$extraOption .= ' data-id="'.$champ->id.'" ';
			}

			if ($champ->idType == "13" || $champ->idType == "19") { // formule monétaire(16)-date(19)
				if ($champ->formule && $champ->formule != "") {
					$extraOption .= ' readonly="readonly" ';
					if ($champ->idType == "19") {
						//$extraOption .= ' disabled="disabled" ';//pour save en bdd
					}
					$extraOption .= ' data-formule="'.($champ->formule ? substr($champ->formule, 0, -1) : "").'" ';
				}
			}
			if ($champ->idType == 7 && trim($conf->txtPlaceholderTextarea) != '') {
				$extraOption .= ' placeholder="'.$conf->txtPlaceholderTextarea.'" ';
			}

			$extraOption .= ' data-idtype="'.$champ->idType.'"';

			## si le premier champ est un champ date, on met un input vide, pour éviter l'auto open du date picker
			if($ii == 0 && $champ->idType == 2) {
				$html .= '<input type="hidden" autofocus />';
			}

			if ($numLigne == 0) {
				$html .= '<div class="col-md-12">';
			}

			if ($champ->row > $numLigne) {
				//if($numLigne>0){
				//$html .= '<div class="col-md-12">';
				//}
				$html .= '<div class="clearfix"></div>';
				$numLigne = $champ->row;
			}

			if ($champ->column == 2 && empty($columns[$champ->row][1])) {
				$html .= '<div class="col-md-4"><!-- col1 --></div>';
				$columns[$champ->row][1] = 4;
			} elseif ($champ->column == 3) {
				if (empty($columns[$champ->row][1])) {
					$html .= '<div class="col-md-4"><!-- col1 --></div>';
					$columns[$champ->row][1] = 4;
				}
				if (empty($columns[$champ->row][2]) && $columns[$champ->row][1] == 4) {
					$html .= '<div class="col-md-4"><!-- col2 --></div>';
					$columns[$champ->row][2] = 4;
				}
			}

			$html .= '<div class="col-md-'. 4 * $champ->tailleColumn .'">';

			// type html
			$extraHtml = '';
			$extraHtmlCss = '';
			if ($champ->idType == 10) {
				$extraHtml = $extraOption;
				$extraHtmlCss = " id='".$champ->idCss."' ";
			}

			$classCss = '';
			$fieldClassCss = '';
			if ($champ->afficherInfos == 1) {
				$classCss .=  "showinfos ";
			}
			if ($champ->idType == 6) {
				$classCss .=  "showMailTo ";
			}
			if ($champ->styleCss) {
				$fieldClassCss .=  "borderStyle ";
			}
			if ($champ->idType == 14) {
				$fieldClassCss .=  "plg-intlTelInput-ms ";
			}

			if($champ->modifierListe == 1 && ($champ->idType == 3 || $champ->idType == 18)){
				$classCss .=  "modifierListe-ms ";
				$fieldClassCss .=  "modifierListe-ms ";
			}

			$lableOptions = ' data-title="'.$champ->texteInfos.'"';

			$classFormMonetaire = "";
			if (($champ->afficherUnite == "1" && $champ->idType == 13) || $champ->idType == 12) {
				$classFormMonetaire = "type_13 aligner_left";
			}

			$html .= '<div class="form-group has-feedback '.$classCss.' '.$classFormMonetaire.' ">';

			// TEXT
			if ($champ->idType == 1) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// DATE
			elseif ($champ->idType == 2) {
				$extraMinDate = $extraMaxDate = null;
				$inputVal = '';
				if (array_key_exists($champ->id, $result) && sizeof(explode('-', $result[$champ->id])) == 3) {
					$inputVal = date('d-m-Y', strtotime($result[$champ->id]));
				}
				$extraDate = $this->getTableObjet('champs_suivis_dateinterval')->select(array('idChamp' => $champ->id))->current();
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.$inputVal.'" '.$extraOption.' >';

				$plages = $tools->getPlagesDatesBO($extraDate);
				extract($plages);
				$html .= '<script>
							$("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").datepicker({
								"format" : "dd-mm-yyyy",
								startDate:\''.$extraMinDate.'\',
								endDate:\''.$extraMaxDate.'\',
								autoclose:true,
								language:\'fr\',
							}).on("changeDate",function(ev) {
								let value = moment(ev.date).format("DD-MM-YYYY");
								$("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").attr("value", value);

								if ($("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").parent().hasClass("has-error")) {

									$("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").parent().removeClass("has-error")

									$("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").parent().find("small").remove();
								}
							});
						</script>';
			}

			// LIST
			elseif ($champ->idType == 3 || $champ->idType == 18) {
				if ($champ->equivalentSql == "civilite") {
					$select = $this->getTableObjet('civilites')->select(array())->toArray();
					usort($select, function ($a, $b) {
						return strcmp($a["nom"], $b["nom"]);
					});

					if (count($select) > 0) {
						$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'" class="editable" data-msgid="l_'.$champ->name.'_'.$champ->id.'"> '.$translated['lTranslation'][$champ->id].' </label>';

						$html .= '<select data-id-select="'.$champ->id.'" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';

						$emptyOption = "t_Choisissez";
						$html .= '<option value>'.html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8").'</option>';

						foreach ($select as $option) {
							$selected = "";
							if ((array_key_exists($champ->id, $result) && $result[$champ->id] == $option['id']) || (isset($locAcc) && !empty($locAcc) && $locAcc->civilite == $option['id'])) {
								$selected = "selected";
							}

							// Liste des valeurs du champs 2 lesquels sont réliés à chaque option du val1
							$html .= '<option '.$selected.' value="'.$option['id'].'">'.$option['nom'].'</option>';
						}

						$html .= '</select>';
					}
				} elseif ($champ->equivalentSql == "sexe") {
					$select = $this->getTableObjet('sexe')->select(array())->toArray();
					usort($select, function ($a, $b) {
						return strcmp($a["nom"], $b["nom"]);
					});

					if (count($select) > 0) {
						$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'" class="editable" data-msgid="l_'.$champ->name.'_'.$champ->id.'"> '.$translated['lTranslation'][$champ->id].' </label>';

						$html .= '<select data-id-select="'.$champ->id.'" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';

						$emptyOption = "t_Choisissez";
						$html .= '<option value>'.html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8").'</option>';

						foreach ($select as $option) {
							$selected = "";
							if ((array_key_exists($champ->id, $result) && $result[$champ->id] == $option['id']) || (isset($locAcc) && !empty($locAcc) && $locAcc->sexe == $option['id'])) {
								$selected = "selected";
							}

							// Liste des valeurs du champs 2 lesquels sont réliés à chaque option du val1
							$html .= '<option '.$selected.' value="'.$option['id'].'">'.$option['nom'].'</option>';
						}

						$html .= '</select>';
					}
				} elseif (!$champ->sourceListe && strpos($champ->equivalentSql, 'catalogues_') !== false) {
					//on cherche les catalogues
					$idTypeCatalogue = str_replace('catalogues_', '', $champ->equivalentSql);
					$newOption = false;

					if ($_SESSION['USERDROIT']['liste-btn-creer-catalogue-fiche-usager'] == 'W' || $_SESSION['USERDROIT']['liste-btn-creer-catalogue-fiche-usager'] == 'R') {
						//$cataOptions[-1] = 'Nouveau';
						$newOption = true;
					}
					$idCatalogue = !empty($result[$champ->id]) ? $result[$champ->id] : null;
					$cataOptions = $this->getCatalogueTable()->getCataloguesSelectItems($idTypeCatalogue, array('newOption' => $newOption, 'idCatalogue' => $idCatalogue, 'gestId' => $gestId));


					$extraOption .= ' data-idtypecatalogue="'.$idTypeCatalogue.'"';

					$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='NULL'";
					if ($champ->idType == 3 || $champ->idType == 18) {
						$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='".
						$champ->itemsRequiredToActivateSelect2."'";
					}

					$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'" class="editable" data-msgid="l_'.$champ->name.'_'.$champ->id.'"> '.$champ->libelle.' </label>';

					$selectHtml = '<select '.$itemsRequiredToActivateSelect2.' data-id-select="'.$champ->id.'" class="form-control champCatalogue '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';

					$emptyOption = "t_Choisissez";
					$selectHtml .= '<option value>'.html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8").'</option>';

					$idCatalogue = 0;
					foreach ($cataOptions as $id => $val) {
						$selected = "";
						if ((array_key_exists($champ->id, $result) && $result[$champ->id] == $id)) {
							$selected = "selected";
							$idCatalogue = $id;
						}

						// Liste des valeurs du champs 2 lesquels sont réliés à chaque option du val1
						$selectHtml .= '<option '.$selected.' value="'.$id.'">'.$val.'</option>';
					}

					$selectHtml .= '</select>';
					$hide = '';
					if (!$idCatalogue) {
						$hide = 'display:none;';
					}
					$html .= '<a href="javascript:void(0)" class="showCatalogueDetail pull-right " data-idcatalogue="'.$idCatalogue.'" data-idtype="'.$idTypeCatalogue.'" data-idsuivis="'.$idSuivis.'" style="'.$hide.'"><i class="fa fa-eye"></i></a>';
					$html .= $selectHtml;
				} else {
					//$select = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
					$valeurBdd = (array_key_exists($champ->id, $result) && $result[$champ->id]) ? $result[$champ->id] : null;
					$select = $this->getSelectOptions($champ->sourceListe, $champ->options, array('idResa' => $idResa, 'idDp' => $idDp, 'valeurBdd' => $valeurBdd));
					$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';

					// On cherche si le champ est rélié à un autre champ
					$champsAssociation = $this->getTableObjet('champs_association')
					->select(array('idChamp1' => (int) $champ->id, 'idTypeSuivis' => (int) $idTypeSuivis))
					->toArray();
					// On indique que ce champ est lié au champ de la bdd
					$champLinkedTo = "";
					if (count($champsAssociation) > 0) {
						$res = [];
						for ($i = 0; $i < count($champsAssociation); $i++) {
							$res[] = $champsAssociation[$i]['idChamp2'];
						}
						$champLinkedTo = implode("-", array_unique($res));
					}

					$isMultiple = $champ->idType == 18 ? "multiple='multiple'" : "";

					$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='NULL'";
					if ($champ->idType == 3 || $champ->idType == 18) {
						$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='".
						$champ->itemsRequiredToActivateSelect2."'";
					}

					$html .= '<select '.$itemsRequiredToActivateSelect2.' '.$isMultiple.' class="form-control '.$fieldClassCss.'" data-id-select="'.$champ->id.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' data-linked-to="'.$champLinkedTo.'">';

					$valSuivisMultiple = "";
					if ($isMultiple !== "") {
						$demandes_suivis = $this->getTableObjet('suivis_values')
						->select(array('idChamp' => $champ->id, 'idSuivis' => $idSuivis))->current();
						$valSuivisMultiple = $demandes_suivis->valeur;
					}

					// Ajout du champ vide par défaut
					// if (count($select) <= intval($champ->itemsRequiredToActivateSelect2))
					if ($champ->idType != 18) {
						$emptyOption = "t_Choisissez";
						$emptyLabel = html_entity_decode($translator->translate($emptyOption), ENT_NOQUOTES, "UTF-8");

						$allEmpty = true;
						if (count($result) >= 0) {
							foreach ($result as $key => $value) {
								if ($value != "") {
									$allEmpty = false;
								}
							}
						}

						$emptySelected =  !$allEmpty ? "selected" : "";
						// $html .= '<option data-val-linked="" '.$emptySelected.' value="'.$emptyLabel.'">'.$emptyLabel.'</option>';
						$html .= '<option data-val-linked="" '.$emptySelected.' value="">'.$emptyLabel.'</option>';
					}

					// var_dump($html);die();
					foreach ($select as $option) {
						$isMultipleSelected = "";
						if ($isMultiple !== "") {
							if (in_array($option->id, explode(",", $valSuivisMultiple))) {
								// var_dump($valDemandeMultiple);die();
								$isMultipleSelected = "selected";
							}
						}

						// Liaison entre valeurs de chaque champ
						$val2Linked = [];
						foreach ($champsAssociation as $key => $row) {
							if ($row['idVal1'] == $option->id) {
								$val2Linked[] = $row['idVal2'];
							}
						}

						// Liste des valeurs du champs 2 lesquels sont réliés chaque option du val1
						$val2Linked = count($val2Linked) > 0 ? implode("-", array_unique($val2Linked)) : "";
						$disabled = $option->deleted == 1 ? 'disabled' : '';

						$html .= '<option '.$isMultipleSelected.' data-val-linked="'.$val2Linked.'" value="'.$option->id.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id] == $option->id ? 'selected' : '').' '.$disabled.' >'.$option->valeur.'</option>';
					}
					$html .= '</select>';
				}
			}

			// DOC
			elseif ($champ->idType == 4) {
				$fileExist = file_exists($file);
				$champsDoc[] = $champ;
				$html .= '<div class="document">';
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$value = array_key_exists($champ->id, $result) ? $result[$champ->id] : '';

				if(!$disabled) {
					$html .= '<input type="file" class="uploadDoc '.$champ->idCss.' '.$fieldClassCss.'" id="'.$champ->idCss.'" name="file_'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';

					$html .= '<br /><span class="fl">'.($translator->translate('l_parcourir')).'</span>';
					$html .= '<div id="progress_'.$champ->equivalentSql.'" class="progress">';
					$html .= '<div class="progress-bar progress-bar-success"></div>';
					$html .= '</div>';
				}
				$htmlResponseChampDoc = '<div id="reponse_'.$champ->equivalentSql.'" class="msg reponse">';
				// ici la div contenant le liens du message et le btn supprime doit étre sortis de la div de l'input elle seras insérer aprés
				if ($value) {
					if ($idLogement) {
						$file = getcwd().'/public/docs/logements/'.$idLogement.'/suivis/'.$value;
					} else {
						$file = getcwd().'/public/docs/locataires/'.$idLocataire.'/suivis/'.$value;
					}
					if (file_exists($file)) {
						if (!$disabled) {
							$htmlResponseChampDoc .= "<span id='delete_".$champ->equivalentSql."' class='link'><i class='fa fa-2x fa-times red'></i></span> ";
						}
						if ($idLogement) {
							$htmlResponseChampDoc .= "<a class='pj-link' href='".$this->getBaseUrl().'/docs/logements/'.$idLogement.'/suivis/'.$value."' target='_blank'>";
						} else {
							$htmlResponseChampDoc .= "<a class='pj-link' href='".$this->getBaseUrl().'/docs/locataires/'.$idLocataire.'/suivis/'.$value."' target='_blank'>";
						}

						$htmlResponseChampDoc .= $value;
						$htmlResponseChampDoc .= "</a>";
					}
				} else {
					$value = "";
				}
				$htmlResponseChampDoc .= '</div>';
				// Fin bloc response insérer plus tard

				$html .= '<input type="hidden" name="'.$champ->equivalentSql.'" id="idPjName_'.$champ->equivalentSql.'" value="'.$value.'" />';

				$html .= '<input type="hidden" name="pj-href" id="idPjHref'.$champ->equivalentSql.'" value="'.$this->getBaseUrl().'" />';
				$html .= '</div>';
			}

			// NB
			elseif ($champ->idType == 5) {
				$min = $champ->valeurMin ? 'min="'.$champ->valeurMin.'"' : "";
				$max = $champ->valeurMax ? 'max="'.$champ->valeurMax.'"' : "";
				if ($champ->valeurMin) {
					$validator['fields'][$champ->equivalentSql]['validators']['greaterThan'] = array('value' => $champ->valeurMin);
				}
				if ($champ->valeurMax) {
					$validator['fields'][$champ->equivalentSql]['validators']['lessThan'] = array('value' => $champ->valeurMax);
				}

				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="number" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' '.$min.' '.$max.' >';
			}

			// EMAIL
			elseif ($champ->idType == 6) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="email" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// TEXTAREA
			elseif ($champ->idType == 7) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<textarea class="form-control type_7 '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" rows="'.$champ->tailleRow.'" cols="'.$champ->tailleColumn.'" '.$extraOption.' >'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'</textarea>';
			}

			// CHECKBOX
			elseif ($champ->idType == 8) {
				$checked = '';
				if ((array_key_exists($champ->id, $result) && $result[$champ->id]) || (empty($result) && $champ->valeurParDefaut == 1)) {
					$checked = 'checked';
				}
				$html .= '<input id="'.$champ->idCss.'" class="'.$fieldClassCss.'" name="'.$champ->equivalentSql.'" type="checkbox" value="1" '.$checked.'  '.$extraOption.' > <label '.$lableOptions.'>'.$champ->libelle.'</label>';
			}

			// RADIO
			elseif ($champ->idType == 9) {
				//$radios = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				// $radios = $this->getSelectOptions($champ->sourceListe);
				// $html .= '<label style="width:100%;">'.$champ->libelle.'</label>';
				// foreach($radios as $option){
				// 	$html .= '<div style="width:100%;">';
				// 	$html .= '<input id="'.$option->id.'" name="'.$champ->equivalentSql.'" type="radio" value="'.$option->id.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id]==$option->id?'checked':'').' '.$extraOption.' >'.$option->valeur;
				// 	$html .= '</div>';
				// }

				$radios = explode(";", $champ->options);
				$html .= '<div class="'.$fieldClassCss.'"><label class="radio-legend" '.$lableOptions.' style="width:100%;">'.$champ->libelle.'</label>';

				// $translatedList = $this->loadListetranslationForm($locale, $champ->id);
				foreach ($radios as $option) {
					$html .= '<label class="margin-right-10"><input style="margin-right:5px;" id="'.$champ->id.'-'.$option.'" name="'.$champ->equivalentSql.'" type="radio" value="'.$option.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id] == $option ? 'checked' : '').' '.$extraOption.' >'.$option.'</label>';
				}

				$html .= '</div>';
			}

			// HTML
			elseif($champ->idType == 10) {
				$html .= '<div '.$extraHtmlCss.' '.$extraHtml.' class="'.$fieldClassCss.'"><p>'.$champ->description.'</p></div>';
			}

			// PASS
			elseif ($champ->idType == 11) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="password" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';
			}

			//Heure
			elseif ($champ->idType == 17) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control input-heure '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
				$validator['fields'][$champ->equivalentSql]['validators']['regexp'] = array('regexp' => '^(((([0-1][0-9])|(2[0-3]))((:?[0-5][0-9])|(:?[0-5][0-9]:?[0-5][0-9])))|(24:?00))$');
			} else {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control '.$fieldClassCss.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			$html .= '</div>';
			if($htmlResponseChampDoc) {
				$html .= $htmlResponseChampDoc;
			}
			$html .= '</div>';
			if ($champ->column == 1 && $columns[$champ->row][1] <= 8) {
				if (empty($columns[$champ->row][2]) && $columns[$champ->row][1] == 4) {
					$html .= '<div class="col-md-4"><!-- col2 --></div>';
					//$columns[$champ->row][2] = 4;
				}
				if ((empty($columns[$champ->row][3]) && $columns[$champ->row][1] <= 8) && empty($columns[$champ->row][2])) {
					$html .= '<div class="col-md-4"><!-- col3 --></div>';
					//$columns[$champ->row][3] = 4;
				}
			}
			$ii++;
			$htmlResponseChampDoc = false;

		}

		// VALIDATION BUTTON
		$html .= '<div class="clearfix"></div>';

		$inputHiddenAction = "";
		if (in_array(-2, $idsChampsActions)) {
			$inputHiddenAction = '<input type="hidden" name="idTypeLocataire" class="form-control" value="" data-action="1" />';
		}
		if (in_array(-3, $idsChampsActions)) {
			$inputHiddenAction .= '<input type="hidden" name="payerDG" class="form-control" value="" data-action="1" />';
		}
		if (in_array(-4, $idsChampsActions)) {
			$inputHiddenAction .= '<input type="hidden" name="idCampagne" class="form-control" value="'.$idCampagne.'" data-action="1" />';
		}


		$html .= '<div class="col-md-12">
						<input type="hidden" name="idResa" value="'.$idResa.'">
						<input type="hidden" name="idDp" value="'.$idDp.'">
						<input type="hidden" name="idLogement" value="'.$idLogement.'" class="suivis-idLogement">
						<input type="hidden" name="idLocataire" value="'.$idLocataire.'" class="suivis-idLocataire">
						<input type="hidden" name="idFormulaireCampagne" value="'.$idFormulaireCampagne.'" class="suivis-idFormulaireCampagne">
						'.$inputHiddenAction.'
				</div>';
		return array('html' => $html, 'validator' => $validator, 'champsDoc' => $champsDoc);
	}

	public function getHistoriqueSMSTable()
	{
		if (!$this->historiqueSMSTable) {
			$sm = $this->getServiceLocator();
			$this->historiqueSMSTable = $sm->get('Reservation\Model\HistoriqueSMSTable');
		}
		return $this->historiqueSMSTable;
	}

	public function getHistoriqueAlertTable()
	{
		if (!$this->historiqueAlertTable) {
			$sm = $this->getServiceLocator();
			$this->historiqueAlertTable = $sm->get('Reservation\Model\HistoriqueAlertTable');
		}
		return $this->historiqueAlertTable;
	}

	public function getChampsModalAction()
	{
		$request = $this->getRequest();
		$from = '';
		if ($request->isGet()) {
			$paramsContentFromResaController = $this->params('myObject');
			$paramsContentFromResaController = json_decode($paramsContentFromResaController, true);

			// var_dump($paramsContentFromResaController['from']);die();
			if (count($paramsContentFromResaController) > 0) {
				$listId = (object) $paramsContentFromResaController['listId'];
				$from = "systeme";
			}
		}

		if ($request->isXmlHttpRequest()) {
			$listId = $request->getPost('listId');
		}

		$view = new JsonModel(array(
			'champModalHtml' => $this->loadChampsModal($listId == 'id-modeDp' ? 'dp' : null, $from),
		));

		$view->setTerminal(true);
		return $view;
	}

	##Action forwarder pour charger le champs modal
	public function loadChampsModalForwardAction()
	{
		$mode =  $this->params()->fromRoute('mode', '');
		$params =  $this->params()->fromRoute('params', array());
		$sousMode = '';
		if(!empty($params) && array_key_exists('sousMode', $params)) {
			$sousMode = $params['sousMode'];
		}
		return $this->loadChampsModal($mode, '', array('sousMode' => $sousMode));
		exit();
	}


	public function loadChampsModal($mode = null, $from = '', $params = array())
	{

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$sousMode = !empty($params['sousMode']) ? $params['sousMode'] : '';

		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		/*if ($mode == 'dp') {
			$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>'dp'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>'dp'));
		}elseif($mode == 'facture'){
			$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>'facture'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>'facture'));
		}elseif($mode == 'prestation'){
			$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>'prestation'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>'prestation'));
		} elseif($mode == 'logements') {
			$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>'logements'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>'logements'));
		} else{
			$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>'reservations'));
			$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode'=>'reservations'));
		}*/
		$modeListe = $mode ? $mode : 'reservations';
		//$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile,array('mode'=>$modeListe));
		$catsDeBase = $this->getChampCatTable()->getCatDeBase();
		$catRows = $this->getChampCatTable()->getCatsTree(array('mode' => $modeListe, 'idProfile' => $idProfile, 'gestId' => $gestId, 'typeRetourChamps' => 'avecChamps'));
		$allChampsResult = $this->getChampCatTable()->getAllChamps(array('mode' => $modeListe));

		//champs pms pour les modèles documents :
		$tools = new Tools();
		if($from == "systeme") {
			$catsDeBase['champs_pms'] = 'Autres';
			## champs PMS
			$champPMS = array();
			$champsResult = $this->getTableObjet('champs_pms')->select();
			$champsPMSLibs = $tools->getChampsPMSLibs();
			foreach($champsResult as $c) {
				if(array_key_exists($c->equivalentSql, $champsPMSLibs)) {
					$c->nom = $champsPMSLibs[$c->equivalentSql];
				}
				$champPMS[] = (object)array('champName' => $c->equivalentSql, 'libelle' => $c->nom);
			}
			$obj = (object)array('categorie' => 'PMS', 'id' => 'pms', 'champs' => $champPMS);
			$catRows['champs_pms']['pms'] = $obj;

			## champs structure
			$champsStruc = array();
			$champsStruc[]	= (object)['libelle' => 'batiment', 'champName' => 'batiment'];
			$champsStruc[]	= (object)['libelle' => 'residence', 'champName' => 'residence'];
			$champsStruc[]	= (object)['libelle' => 'residence_nom', 'champName' => 'residence_nom'];
			$champsStruc[]	= (object)['libelle' => 'residence_adresse', 'champName' => 'residence_adresse'];
			$champsStruc[]	= (object)['libelle' => 'residence_codePostal', 'champName' => 'residence_codePostal'];
			$champsStruc[]	= (object)['libelle' => 'residence_ville', 'champName' => 'residence_ville'];
			$champsStruc[]	= (object)['libelle' => 'residence_telephone', 'champName' => 'residence_telephone'];
			$champsStruc[]	= (object)['libelle' => 'residence_email', 'champName' => 'residence_email'];
			$champsStruc[]	= (object)['libelle' => 'nomStructure', 'champName' => 'nomStructure'];
			$champsStruc[]	= (object)['libelle' => 'responsableStructure', 'champName' => 'responsableStructure'];
			$champsStruc[]	= (object)['libelle' => 'adresseStructure1', 'champName' => 'adresseStructure1'];
			$champsStruc[]	= (object)['libelle' => 'adresseStructure2', 'champName' => 'adresseStructure2'];
			$champsStruc[]	= (object)['libelle' => 'codePostalStructure', 'champName' => 'codePostalStructure'];
			$champsStruc[]	= (object)['libelle' => 'villeStructure', 'champName' => 'villeStructure'];
			$champsStruc[]	= (object)['libelle' => 'telephoneStructure', 'champName' => 'telephoneStructure'];
			$champsStruc[]	= (object)['libelle' => 'faxStructure', 'champName' => 'faxStructure'];
			$champsStruc[]	= (object)['libelle' => 'emailStructure', 'champName' => 'emailStructure'];
			$champsStruc[]	= (object)['libelle' => 'logo', 'champName' => 'logo'];
			$champsStruc[]	= (object)['libelle' => 'imageSignature', 'champName' => 'imageSignature'];
			$champsStruc[]	= (object)['libelle' => 'imageTampon', 'champName' => 'imageTampon'];
			$obj = (object)array('categorie' => 'Structure', 'id' => 'structure', 'champs' => $champsStruc);
			$catRows['champs_pms']['structure'] = $obj;

			## champs SEPA
			$champsSepa = array();
			$champsSepa[]	= (object)['libelle' => 'Numéro de mandat SEPA', 'champName' => 'numeroMandatSEPA'];
			$champsSepa[]	= (object)['libelle' => 'IBAN', 'champName' => 'rib_iban'];
			$champsSepa[]	= (object)['libelle' => 'BIC', 'champName' => 'rib_bic'];
			$champsSepa[]	= (object)['libelle' => 'Titulaire du compte', 'champName' => 'rib_nomrib'];
			$obj = (object)array('categorie' => 'SEPA-RIB', 'id' => 'sepa', 'champs' => $champsSepa);
			$catRows['champs_pms']['sepa'] = $obj;

			## prestations
			$champsPrest = array();
			$champsPrest[]	= (object)['libelle' => 'Libellé', 'champName' => 'Presta_libelle_1'];
			$champsPrest[]	= (object)['libelle' => 'Montant', 'champName' => 'Presta_MtUnit_1'];
			$champsPrest[]	= (object)['libelle' => 'Code', 'champName' => 'Presta_Code_1'];
			$champsPrest[]	= (object)['libelle' => 'Quantité', 'champName' => 'Presta_Qte_1'];
			$champsPrest[]	= (object)['libelle' => 'Montant TTC', 'champName' => 'Presta_MtTTC_1'];
			$champsPrest[]	= (object)['libelle' => 'Montant HT', 'champName' => 'Presta_MtHT_1'];
			$champsPrest[]	= (object)['libelle' => 'TVA', 'champName' => 'Presta_Tva_1'];
			$obj = (object)array('categorie' => 'Prestations', 'id' => 'prestation', 'champs' => $champsPrest);
			$catRows['champs_pms']['prestation'] = $obj;

			## Autres
			$champsAutre = array();
			$champsAutre[]	= (object)['libelle' => 'Date du jour', 'champName' => 'date_now'];
			$champsAutre[]	= (object)['libelle' => 'Total redevance', 'champName' => 'total_redevance'];
			$champsAutre[]	= (object)['libelle' => 'Solde antérieur', 'champName' => 'solde_anterieur'];
			$champsAutre[]	= (object)['libelle' => 'Solde caution', 'champName' => 'soldeCaution'];
			$champsAutre[]	= (object)['libelle' => 'Reste à régler', 'champName' => 'resteARegler'];
			$champsAutre[]	= (object)['libelle' => 'Total période', 'champName' => 'totalPeriode'];
			$champsAutre[]	= (object)['libelle' => 'Total facture', 'champName' => 'totalFacture'];
			$champsAutre[]	= (object)['libelle' => 'Solde facture', 'champName' => 'soldeFacture'];
			$champsAutre[]	= (object)['libelle' => 'Montant réglé', 'champName' => 'montantRegle'];
			$champsAutre[]	= (object)['libelle' => 'Montant prestation à verser', 'champName' => 'montantPrestationAVerser'];
			$champsAutre[]	= (object)['libelle' => 'Total', 'champName' => 'total'];
			$champsAutre[]	= (object)['libelle' => 'Observations', 'champName' => 'observations'];
			$obj = (object)array('categorie' => 'Autres', 'id' => 'autres', 'champs' => $champsAutre);
			$catRows['champs_pms']['autres'] = $obj;
		}

		//print_r($catRows['champs_formulaires']['formulaires'][8][81]['champs']);exit();

		$champLibs = $allChampsResult;
		$allChamps = $this->translateChamps($allChampsResult);
		//print_r($champLibs);exit();

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/champsmodal')
		->setVariables(array(
				'catRows' => $catRows,
				'allChamps'	=> $allChamps,
				'mode' => $mode ? $mode : 'reservations',
				'listeChampsAffiches' => array(),
				'champLibs' => $champLibs,
				'catsDeBase' => $catsDeBase,
				'from' => $from,
				'sousMode' => $sousMode,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}


	private function translateChamps($allChamps = array())
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf->afficherTradChampsBO == '1') {
			$tools = new Tools();
			$toutLesChamps = $this->getToutLesChamps();

			$fichier = getcwd()."/module/Application/language/fr_FR.po";
			try {
				$contents = $tools->get_contents_tab($fichier);
			} catch (\Exception $ex) {
				$contents = array();
			}
			if (!empty($contents)) {
				$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
				$translator->setLocale('fr_FR');

				foreach ($toutLesChamps as $champName => $champ) {
					$lmsgid = 'l_'.$champ->name.'_'.$champ->id;
					if (array_key_exists($lmsgid, $contents) && array_key_exists($champName, $allChamps)) {
						$allChamps[$champName] = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");
					}
				}
			}
		}
		return $allChamps;
	}

	private function getAllChampsTranslation()
	{
		$return = array();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf->afficherTradChampsBO == '1') {
			$tools = new Tools();
			$toutLesChamps = $this->getToutLesChamps();

			$fichier = getcwd()."/module/Application/language/fr_FR.po";
			try {
				$contents = $tools->get_contents_tab($fichier);
			} catch (\Exception $ex) {
				$contents = array();
			}
			if (!empty($contents)) {
				$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
				$translator->setLocale('fr_FR');

				foreach ($toutLesChamps as $champName => $champ) {
					$lmsgid = 'l_'.$champ->name.'_'.$champ->id;
					if (array_key_exists($lmsgid, $contents)) {
						$return[$champName] = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");
					}
				}
			}
		}
		return $return;
	}

	private function getToutLesChamps()
	{
		$tableCL = $this->getTableObjet('champs_formulaires');
		$select = $tableCL->getSql()->select();
		$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
		$select->where(array('champs_formulaires.active' => 1, 'formulaires.active' => 1 ));

		$result = $tableCL->selectWith($select);
		$rows = array();
		foreach ($result as $row) {
			$rows[$row->equivalentSql] = $row;
		}
		return $rows;
	}

	public function getChampCatTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		return new ChampsCatsTable($adapter);
	}

	//archiver demande, resai, dosser bredea
	public function archiverBredea($cData = array(), $idApiPms = 1)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$ret = false;
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				$this->initPMS($idApiPms);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
					}
				}
				if ($bredea) {
					##viaPMS $bredea = new BredeaSql($conf->siteDemande);
					$ret = $bredea->archiver($cData);
					$bredea->closeConnect();
					$this->pms	= null;
				}
			} catch (\Exception $ex) {
				echo $ex->getMessage();
			}
		} else {
			$ret = true;
		}
		return $ret;
	}

	public function savefiltrefandeauAction()
	{
		$sessFB = new Container('filtreBandeau');
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$post = $request->getPost()->toArray();
			$sessFB->filtres = $post;
			$view = new JsonModel(array(
						'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function getFiltresTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		return new FiltresTable($adapter);
	}

	public function getCampagneTable()
	{
		if (!$this->campagneTable) {
			$sm = $this->getServiceLocator();
			$this->campagneTable = $sm->get('Reservation\Model\CampagneTable');
		}
		return $this->campagneTable;
	}

	private function getModeleMailChamps($params)
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$idModele = !empty($params['idModele']) ? $params['idModele'] : 0;
		$idCategorie = !empty($params['idCategorie']) ? $params['idCategorie'] : 0;
		$modeListe = !empty($params['modeListe']) ? $params['modeListe'] : "";
		$isResa = !empty($params['isResa']) ? $params['isResa'] : 0;
		$fromController = !empty($params['fromController']) ? $params['fromController'] : 'liste';
		$exportListe = !empty($params['exportListe']) ? $params['exportListe'] : '';//si on joint l export d'une liste au mail ou non

		$mode = array('mode' => 'reservations');

		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
		//$catRows = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile, $mode);
		$allChampsResult = $this->getChampCatTable()->getAllChamps($mode);
		$allChamps = $this->translateChamps($allChampsResult);

		$catRes = [];
		$continue = false;
		if (strpos(strtolower($modeListe), "suivis") !== false) {
			$mode = array('mode' => 'suivis');
			$continue = true;
		} elseif (strpos(strtolower($modeListe), "formulaire") !== false) {
			$mode = array('mode' => 'formulaires');
			$continue = true;
		}

		$catsDeBase = $this->getChampCatTable()->getCatDeBase();
		$options = array('mode' => $mode['mode'], 'idProfile' => $idProfile, 'gestId' => $gestId, 'typeRetourChamps' => 'avecChamps');
		$catRows = $this->getChampCatTable()->getCatsTree($options);

		$allChamps["pj_refuse"] = "pj_refuse";
		$allChamps["pj_manquante"] = "pj_manquante";
		$allChamps["demande_raison_impossibilite"] = "demande_raison_impossibilite";

		// echo "<pre>";
		// var_dump($catRows[-1]);die();
		// echo "</pre>";
		// die();

		//$catRows[-1]['champs'][] = "pj_refuse";
		//$catRows[-1]['champs'][] = "pj_manquante";
		//$catRows[-1]['champs'][] = "demande_raison_impossibilite";
		$champsExtra = array();

		if (!in_array("demande_raison_impossibilite", $allChamps)) {
			$allChamps['demande_raison_impossibilite'] = "demande_raison_impossibilite";
			$champsExtra[] = "demande_raison_impossibilite";
		}

		if (!in_array("idDemande", $allChamps)) {
			$allChamps['idDemande'] = "idDemande";
			$champsExtra[] = "idDemande";
		}

		if (!in_array("urlDemande", $allChamps)) {
			$allChamps['urlDemande'] = "urlDemande";
			$champsExtra[] = "urlDemande";
		}

		if (!in_array("m_demande_etatTravaux", $allChamps)) {
			$allChamps['m_demande_etatTravaux'] = "m_demande_etatTravaux";
			$champsExtra[] = "m_demande_etatTravaux";
		}

		if (!in_array("dateCreationDemande", $allChamps)) {
			$allChamps['dateCreationDemande'] = "dateCreationDemande";
			$champsExtra[] = "dateCreationDemande";
		}

		if (!in_array("pj_refuse", $allChamps)) {
			$allChamps['pj_refuse'] = "pj_refuse";
			$champsExtra[] = "pj_refuse";
		}

		if (!in_array("pj_manquante", $allChamps)) {
			$allChamps['pj_manquante'] = "pj_manquante";
			$champsExtra[] = "pj_manquante";
		}

		foreach ($champsExtra as $champ) {
			$obj1 = new \stdClass();
			$obj1->champName = $champ;
			$obj1->idCategorie = -1;

			$catRows['autres'][-1]->champs[] = $obj1;
		}

		if ($continue) {
			$allChampsResults = $this->getChampCatTable()->getAllChamps($mode);
			//$catRowss = $this->getChampCatTable()->fetchCategoriesByProfile($idProfile, $mode);
			$catRowss = $this->getChampCatTable()->getCatsTree($options);
			$allChampss = $this->translateChamps($allChampsResults);

			foreach ($allChampss as $key => $value) {
				$allChamps[$key] = $value;

				$champSuivisRow = $this->getTableObjet('champs_suivis')
				->select(array('name' => $key))->current();

				if ($champSuivisRow->idType == 4) {
					$allChamps[$champSuivisRow->name."_nom"] = $champSuivisRow->libelle."_nom";
				}
			}
			foreach ($catsDeBase as $sourceChamp => $libelle) {
				if (empty($catRows[$sourceChamp])) {
					continue;
				}

				foreach ($catRows[$sourceChamp] as $key => $r) {
					foreach ($catRowss[$sourceChamp] as $key => $rs) {
						if (is_object($rs)) {
							$rs = (array) $rs;
						}
						if (is_object($r)) {
							$r = (array) $r;
						}
						// var_dump($rs['categorie']);
						// var_dump($r['categorie']);die();

						if ($r['categorie'] == $rs['categorie']) {
							// var_dump($rs['champs']);
							if (count($rs['champs']) > 0) {
								foreach ($rs['champs'] as $key => $ch) {
									// var_dump($ch);

									$exist = false;

									if (count($r['champs']) > 0) {
										foreach ($r['champs'] as $key => $rch) {
											// var_dump($rch);die();
											if ($ch == $rch || $ch->champName == $rch->champName) {
												$exist = true;
											}
										}
									}

									if (!$exist) {
										$r['champs'][] = is_object($ch) ? $ch->champName : $ch;
										// si c'est un champ suivi de type doc
										// alors on double
										$champSuivisRow = $this->getTableObjet('champs_suivis')
										->select(array('name' => is_object($ch) ? $ch->champName : $ch))
										->current();

										if ($champSuivisRow->idType == 4) {
											// var_dump($champSuivisRow->idType);
											array_push($r['champs'], (is_object($ch) ? $ch->champName : $ch)."_nom");
										}
									}
								}
							}
						}
					}

					// var_dump($r);die();
					$catRes[] = $r;
				}


				$catRows[$sourceChamp] = count($catRes) > 0 ? $catRes : $catRows[$sourceChamp];
			}
		}

		return array('catRows' => $catRows, 'allChamps' => $allChamps, 'catsDeBase' => $catsDeBase);
	}

	/********************************************************************************************\
										MODULE CAF
	\********************************************************************************************/
	public function verifCodeBailleurAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getResaTable()->setAdapter($adapter);

		$request = $this->getRequest();
		// Point d'entrée du traitement IDEAL CAF
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$resa = $this->getResaTable()->getResaWithPms($idResa);
			$bredea		= null;
			if ($resa) {
				$this->initPMS($resa->idApiPms ?: 1, $idResa);
				$ceri = false;

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
						$ceri = true;
					}
				}
			}


			$codeBailleurOK = false;
			$codeBailleur = '';
			$cp = "";
			$logement = [];
			if ($bredea) {
				##viaPMS $bredea = new BredeaSql();

				//reservation si code bailleur existe
				$scwhere = array('csi_code' => $resa->codeSite);
				$fcsite = $bredea->getRow('001fcsite', $scwhere);

				$sitewhere = array('si_code' => $resa->codeSite);
				$fsite = $bredea->getRow('001fsite', $sitewhere);
				foreach ($fsite as $site => $s) {
					$fsite[$site] = trim(utf8_encode($s));
				}

				if (isset($fcsite['csi_bailleur']) && !empty($fcsite['csi_bailleur'])) {
					if ($resa->typre == 'FA') { // Lire le dossier famille

						$fdosfaWhere = array('dosfa_trait' => 'A', 'dosfa_site' => $resa->codeSite, 'dosfa_typre' => $resa->typre, 'dosfa_nodoss' => $resa->numDossier);
						$fdosfa = $bredea->getRow('001fdosfa', $fdosfaWhere);
						// Logement
						$flogeWhere = array(
											'log_no' => $fdosfa['dosfa_nolog'],
											'log_site' => $fdosfa['dosfa_site'],
									);

						$floge = $bredea->getRow('001floge', $flogeWhere);
					}elseif ($resa->typre == 'PA') { // Lire le dossier famille

						$fdospaWhere = array('dospa_trait' => 'A', 'dospa_site' => $resa->codeSite, 'dospa_typre' => $resa->typre, 'dospa_nodoss' => $resa->numDossier);
						$fdospa = $bredea->getRow('001fdospa', $fdospaWhere);
						// Logement
						$flogeWhere = array(
											'log_no' => $fdospa['dospa_nolog'],
											'log_site' => $fdospa['dospa_site'],
									);

						$floge = $bredea->getRow('001floge', $flogeWhere);
					} else {
						//dossier
						$fdossiWhere = array('dossi_trait' => 'A', 'dossi_site' => $resa->codeSite, 'dossi_typre' => $resa->typre, 'dossi_nodoss' => $resa->numDossier);
						$fdossi = $bredea->getRow('001fdossi', $fdossiWhere);
						// logement
						$flogeWhere = array('log_no' => $fdossi['dossi_nolog'],
										'log_site' => $fdossi['dossi_site']);

						$floge = $bredea->getRow('001floge', $flogeWhere);
						$fclogeWhere = array('clog_no' => $fdossi['dossi_nolog'],
										 'clog_sno' => $fdossi['dossi_snolog'],
										 'clog_site' => $fdossi['dossi_site']);

						$fcloge = $bredea->getRow('001fcloge', $fclogeWhere);
					}
					$codeBailleurOK = true;
					$codeBailleur = $fcsite['csi_bailleur'];
				}

				foreach ($floge as $key => $value) {
					$value = trim(utf8_encode($value));
					$logement[$key] = $value;
				}
			} elseif ($ceri) {

				// echo "<pre>";
				// var_dump($resa);
				// echo "</pre>";
				// die();

				## Création du PMS Generique
				## ~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$pmsGen	= new PmsGen($adapter, $resa->idApiPms);
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms ERROR-exception=".$ex->getMessage());

					echo "erreur dans PMsGen Exception=".$ex->getMessage();
					die();
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms=".$pmsGen->shortPrint());

				if (!$pmsGen) {
					## Pas de PMSgen ??
					## ~~~~~~~~~~~~~~~~
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms Pas de PMSgen ??");
					echo "erreur pas de PMsGen";
					die();
				}

				## Connexion au PMS explicite
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
					if (is_object($pms)) {
						// Récupération du code bailleur et de la raison sociale
						$cmd = "select CODE_BAILLEUR, NOM, NO_ETABL, NOM, CP, VILLE from ETABL";
						$result = $pms->queryObj($cmd);
						if (is_object($result)) {
							$rows	= array();
							foreach ($result as $row) {
								if ($row) {
									## Convertir la réponse à partir du charset de la BDD
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									mb_convert_variables('UTF-8', 'ISO-8859-1', $row);

									if ($row['CODE_BAILLEUR'] != null) {
										$codeBailleurOK = true;
										$codeBailleur = $row['CODE_BAILLEUR'];
									}

									if ($row['CP'] != null) {
										$cp = $row['CP'];
									}

									$rows[]	= $row;
								}
							}



							// echo "\napres importSitesObj_$idApiPms sites="; print_r($rows);
						} else {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : importSitesObj_$idApiPms Err=$result");
						}

						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : pms_$idApiPms pmsClass=".get_class($pms));
					} else {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : pms_$idApiPms ConnectErr=$pms");
						return "erreur dans connectPms";
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : pms_$idApiPms connectPms ERROR-exception=".$ex->getMessage());
					return "erreur dans connectPms Exception=".$ex->getMessage();
				}
			}

			$view = new JsonModel(array('mode' => $ceri ? "ceri" : "bredea",
				"cp" => $cp, 'codeBailleurOK' => $codeBailleurOK, 'codeBailleur' => $codeBailleur, 'floge' => $logement, 'fsite' => $fsite));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	/**
	 * Retourne les informations nécessaires et suffisant pour effectuer le traitement
	 *
	 */
	public function demarcheCafAction()
	{
		$datas = array();
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');

		// Point d'entrée du traitement IDEAL CAF
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$insee_com = $request->getPost('insee_com');

			// on recupère tous les infos infos necessaires afin de pouvoir effectuer la démarche
			$datas = $this->getAllDataCaf($idResa, $insee_com);

			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "IDEAL - Démarche entammé le  ".$dateOperation;
			$log->dataBefore = array();
			$log->dataAfter = $dataFact;
			$log->tableName = "Bredea";
			$log->idReservation = $resa->id;
			$log->idLocataire = $resa->idLocataire;
			$this->getLogsTable()->saveLogs($log);

			// echo "<pre>";
			// print_r($datas);
			// echo "</pre>";
			// die();

			// Adresse du web service + params SOAP
			// $wsdl = 'https://services.caf.fr/gfi-bailleur-web/IdealfluxV1Service/IdealfluxV1Service.wsdl';
			// $options = array(
			//      'uri'=> 'http://schemas.xmlsoap.org/soap/envelope/',
			//      'style'=> SOAP_RPC,
			//      'use'=> SOAP_ENCODED,
			//      'soap_version'=>S OAP_1_1,
			//      'cache_wsdl'=> WSDL_CACHE_NONE,
			//      'trace'=> true,
			//      'encoding'=> 'UTF-8',
			//      'exceptions'=> true,
			//    );

			$xml_doc = $this->fillXmlDataCaf($datas);

			//Parser le fichier XML et le sauvegarder
			$fluxDir = getcwd()."/public/data/SOAP";
			$xml_string = $xml_doc->saveXML();

			$xml_string_path = $fluxDir."XMLBrut.xml";
			file_put_contents($xml_string_path, $xml_string);

			$SOAPReqFilename = "$fluxDir/traitementFluxRequest.xml";
			$sendedSOAPRequestPath = $this->makeSOAPRequestCaf($xml_string, $SOAPReqFilename, $fluxDir);

			// $serviceURL = 'https://services.caf.fr/gfi-bailleur-web/IdealfluxV1Service';
			$serviceURL = 'https://pep.caf.fr/gfi-bailleur-web/IdealfluxV1Service';
			$response_filepath = $this->sendSOAPRequestCaf($serviceURL, $sendedSOAPRequestPath, $fluxDir);

			$responseCnaf = $this->getIDFluxCaf($response_filepath);



			if ($responseCnaf['error'] == true) {
				$view = new JsonModel(array(
										'error' => true,
										'codeError' => $responseCnaf['codeError'],
										'errorMsg' => $responseCnaf['errorMsg'],
										// 'xml_string'=> $xml_string,
										// 'datas' => $datas
									));
			} else {
				// $webAppURL = 'https://services.caf.fr/gfi-bailleur-web/servlet/StartProcess?idFlux='.$responseCnaf['idFlux'];
				$webAppURL = 'https://pep.caf.fr/gfi-bailleur-web/servlet/StartProcess?idFlux='.$responseCnaf['idFlux'];
				$view = new JsonModel(array(
										'error' => false,
										// 'xml_string'=> $xml_string,
										'id_identification' => $responseCnaf['idFlux'],
										'url_web_app' => $webAppURL,
										// 'datas' => $datas1
									));
			}

			$view->setTerminal(true);
			return $view;
		}
	}

	/* Création de la requête SOAP et stockage de celle-ci */

	private function makeSOAPRequestCaf($XML_formularyFile, $SOAPRequestFilePath, $fluxDir)
	{
		// Encode le fichier XML de demande d'APL
		$XMLStrEnc = base64_encode($XML_formularyFile);
		$SOAPRequestStr = file_get_contents("$SOAPRequestFilePath"); // Récupération du fichier SOAP valide mais sans aucune donnée

		/* Cible la balise <flux> de la requête SOAP envoyée et
		 * y ajoute le contenu encodé de la fiche XML
		 */
		$toSendSOAPReqHdlr = new \DOMDocument('1.0', 'utf-8');
		$res = $toSendSOAPReqHdlr->loadXML($SOAPRequestStr);

		if (!$res) {
			RaiseError("ERR_OPENING_XML_FILE");
		}

		$toSendSOAPReqHdlr->loadXML($SOAPRequestStr);
		$XMLStrTxtEnc = $toSendSOAPReqHdlr->createTextNode($XMLStrEnc); // Création du contenu de <flux>

		$FluxTag = $toSendSOAPReqHdlr->getElementsByTagName("flux");
		$fluxTag = $FluxTag->item(0);

		$fluxTag->appendChild($XMLStrTxtEnc);

		$sendedSOAPReq_path = "$fluxDir/req_SOAP_Avec_Infos.xml";

		try {
			/* Je me suis mépris lors de la discussion car je stocke la requête à envoyer dans un fichier */
			$toSendSOAPReqHdlr->save($sendedSOAPReq_path);
		} catch (Exception $e) {
			RaiseError($e->getMessage);
		}

		return $sendedSOAPReq_path;
	}

	public function sendSOAPRequestCaf($serviceURL, $sendedSOAPReq_path, $fluxDir)
	{
		$cURLResponse_filepath = "$fluxDir/response_service.xml";

		/* Je récupère la réponse */
		$cURL_cmdLine = "curl -X POST -d @$sendedSOAPReq_path -E $fluxDir/keyStore.pem -v $serviceURL --insecure --header \"Content-Type:text/xml\" > $cURLResponse_filepath";

		$retval = null;
		exec($cURL_cmdLine, $cURLRet, $retval);

		// echo "Returned with status $retval and output:\n";
		// print_r($cURLRet);
		// die();

		if (!empty($cURLRet)) {
			FB::log("cURL Error : ". $cURLRet);
		}

		return $cURLResponse_filepath;
	}

	/* Le XML est parsé pour retrouver le numéro du flux */
	public function getIDFluxCaf($response_filepath)
	{
		$fluxIDFileContent = file_get_contents($response_filepath);

		$XMLcURLRes = new \DOMDocument('1.0', 'utf-8');
		$XMLcURLRes->loadXML($fluxIDFileContent);

		$codeRetour = $XMLcURLRes->getElementsByTagName("codeRetour");
		$codeRetour = $codeRetour->item(0);
		$codeError = $codeRetour->nodeValue;


		$fluxTag = $XMLcURLRes->getElementsByTagName("idFlux");
		$fluxTag = $fluxTag->item(0);
		$IDFlux = $fluxTag->nodeValue;


		if ($codeError == 0) {
			return array('error' => false, 'idFlux' => $IDFlux );
		} else {
			$errorMsg = '';
			switch ($codeError) {
				case 1:
					$errorMsg = 'Flux absent en entrée du web-service';
					break;
				case 2:
					$errorMsg = 'Flux xml mal formé – Vérifier la structure xml';
					break;
				case 3:
					$errorMsg = 'Flux xml incorrect – Données bailleurs absentes';
					break;
				default:
					$errorMsg = 'Une erreur est survenue';
					break;
			}
			return array('error' => true, 'codeError' => $codeError, 'errorMsg' => $errorMsg);
		}
	}


	private function constructInfosBailleurCAF($residence)
	{
		// Phase production
		// et '123456789 par $residence['idDemandeBailleur']

		$row = $this->getTableObjet('ideal_caf_mode')->select(array('id' => 1))->current();
		$IdentificationNationale = $row->mode == 'production' ? $residence['idNationale'] : 'D0015';
		return array(
				// 'IdentificationNationale' => $residence['idNationale'],
				 // 'IdentificationNationale' => 'D0015',
				'IdentificationNationale' => $IdentificationNationale,
				'RaisonSociale' => $residence['raisonSociale'],
				'IdentificationDemandeBailleur' => $residence['idDemandeInterne']);
	}

	private function constructInfosOrganismeCAF($residence, $getDemandePMS = array())
	{
		if (count($getDemandePMS) > 0) {
			// var_dump($getDemandePMS['RESIDENTS']['NO_LOCATAIRE_CAF']);

			return array(
				'MATRICULE' => $getDemandePMS['RESIDENTS']['NO_LOCATAIRE_CAF'],
			  	'CAFDEMANDE' => $residence['cafDemande'],
			  	// 'CAFORIGINE' => $residence['cafOrigine'],
			  	'IDENTAGENCE' => $residence['cafCodeAgence']
			);
		} else {
			return array(
				'MATRICULE' => $residence['matricule'],
			  	'CAFDEMANDE' => $residence['cafDemande'],
			  	// 'CAFORIGINE' => $residence['cafOrigine'],
			  	'IDENTAGENCE' => $residence['cafCodeAgence']
			);
		}
	}

	private function constructInfosPersonneRespCAF($locataire, $fdosfa, $fdossi, $typre, $getDemandePMS = array(), $resa)
	{
		$prefix = $typre == 'PA' ? 'dospa' : 'dosfa';
		$sexe = ($typre == 'FA' || $typre == 'PA') ? trim($fdosfa[$prefix.'_sexe']) : trim($fdossi['dossi_sexe']);
		$civilite = $sexe == 'M' ? 'MON' : 'MME';

		// echo $fdosfa['dosfa_natio'];die();

		// Recup nationalité
		if (count($getDemandePMS) <= 0) {
			##viaPMS
			$bredea	= $this->pms;
			$natRow = $bredea->getRow('001fnatio', array('nat_code' =>($typre == 'FA' || $typre == 'PA') ? trim($fdosfa[$prefix.'_natio']) : trim($fdossi['dossi_nation'])));
			$activProRow = $bredea->getRow('001factiv', array('act_code' => ($typre == 'FA' || $typre == 'PA') ? trim($fdosfa[$prefix.'_activ']) : trim($fdossi['dossi_activ'])));
		} else {
			$resident = $getDemandePMS['RESIDENTS'];
			return array(
				'TypeRattachement' => 'LOC',
				'NOMNAI' => utf8_decode($resident['NOM']),
				'NOM' => utf8_decode($resident['NOM']),
				'PRENOM' => utf8_decode($resident['PRENOM']),
				'DTNAI' => date('Y-m-d', strtotime($resident['NE_LE'])),
				// 'LOCANAI' => $locataire['lieuNaissance'], // données à saisir à la main
				// 'NATI' => null, // attendre la correspondance avec CF
				'SEXE' => $resident['SEXE'] == "H" ? "M" : "F",
				'QUAL' => $resident['CIVILITE'] == "Monsieur" || $resident['CIVILITE'] == "Mr" ? "MON" : "MME",
				// 'ACT' => $activitePro // Données à saisir à la main
				// 'DDACT' => "1987-02-01"
			);
		}



		$nationalite = '';
		if ($natRow) {
			$nationalite = trim($natRow['nat_code3']) == '' ? 'A' : trim($natRow['nat_code3']);
		}
		// $nationalite =  $natRow ? trim($natRow['nat_code3']) : 'A'; // 'F' (française), 'E' (Espace économique européen), 'A' (Autre) // par défaut c'est autres

		$activitePro = 	$activProRow ? trim($activProRow['act_code3']) : '';

		// var_dump($activitePro);die();

		// echo "<pre>";
		// print_r($natRow['nat_code3']);
		// echo "</pre>";
		// die();
		// dosfa_sexe

		// $cafActivitePro = array('SAL' => 'Salarie',
		// 						'APP' => 'Apprenti',
		// 						'SFP' => 'Stage de formation professionnelle',
		// 						'ETI' => 'Travailleur indépendant',
		// 						'CHO' => 'Chomeur',
		// 						'ETU' => 'Etudiant',
		// 						'RET' => 'Retraite',
		// 						'SSA' => 'Sans activite',
		// 						'AUT' => 'Autres',
		// 					);

		// fcdosfa, fcactiv, cdossi
		$dateNaissance = ($typre == 'FA' || $typre == 'PA') ? trim($fdosfa[$prefix.'_dtnais']) : trim($fdossi['dossi_dtnais']);


		$anne_naiss = substr($dateNaissance, 0, 4); // Format => 31122010
		$mois_naiss = substr($dateNaissance, 4, 2);
		$jour_naiss = substr($dateNaissance, -2);

		// echo $dateNaissance;
		// die();

		## Voir si DDACT est dans les champs complémentaires (champs_caf, noeuf PersonneResp);
		$DDACT = '';
		$bredea	= null;
		if ($resa) {
			$this->initPMS($resa->idApiPms ?: 1, $resa->id);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
					$ceri = true;
				}
			}
		}

		$champsCafPersonneResp = $this->getChampsCafTable()->getChampsCafParNoeud('PersonneResp');
		foreach ($champsCafPersonneResp as $champCaf) {
			if ($champCaf->equivalentCAF == 'DDACT') {
				if ($champCaf->sourcePMS == "bredea") {

					if ($champCaf->tablePMS == "001fdossi") {
						$where = array('dossi_site' => $resa->codeSite, 'dossi_typre' => $resa->typre, 'dossi_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fdosfa") {
						$where = array('dosfa_site' => $resa->codeSite, 'dosfa_typre' => $resa->typre, 'dosfa_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fdospa") {
						$where = array('dospa_site' => $resa->codeSite, 'dospa_typre' => $resa->typre, 'dospa_nodoss' => $resa->numDossier);
					}  elseif ($champCaf->tablePMS == "001fcdossi") {
						$where = array('cdossi_site' => $resa->codeSite, 'cdossi_nodoss' => $resa->numDossier, 'cdossi_table' => '0');
					} elseif ($champCaf->tablePMS == "001fcdosfa") {
						$where = array('cdosfa_site' => $resa->codeSite, 'cdosfa_nodoss' => $resa->numDossier, 'cdosfa_table' => '0');
					} elseif ($champCaf->tablePMS == "001fcdospa") {
						$where = array('cdospa_site' => $resa->codeSite, 'cdospa_nodoss' => $resa->numDossier, 'cdospa_table' => '0');
					}

					$select = $bredea->getRow($champCaf->tablePMS, $where);
					if ($select) {
						if ($champCaf->idType == 2) {
							$jour = substr($select[$champCaf->equivalentPMS], 6, 2);
							$anne = substr($select[$champCaf->equivalentPMS], 0, 4);
							$mois = substr($select[$champCaf->equivalentPMS], 4, 2);
							$val = $anne.'-'.$mois.'-'.$jour;
						} else {
							$val = $select[$champCaf->equivalentPMS];
						}
					}
				} else {
					$val = $champCaf->valeur;
				}

				if ($val) {
					$DDACT = $val;
				}
			}
		}

		return array(
				'TypeRattachement' => 'LOC',
				'NOMNAI' => utf8_decode($locataire->nom),
				'NOM' => utf8_decode($locataire->nom),
				'PRENOM' => utf8_decode($locataire->prenom),
				'DTNAI' => $anne_naiss.'-'.$mois_naiss.'-'.$jour_naiss,
				// 'LOCANAI' => $locataire['lieuNaissance'], // données à saisir à la main
				'NATI' => $nationalite,
				'SEXE' => $sexe,
				'QUAL' => $civilite,
				'ACT' => $activitePro,
				'DDACT' => $DDACT,
			);
	}

	private function constructInfosPersonneRespConCAF($fdosfa, $typre, $getDemandePMS = array())
	{
		$conjoint = array();
		// $activitePro = '';

		if (count($getDemandePMS) > 0) {
			return array();
		} else {
			##viaPMS
			$bredea = $this->pms;
			// Recuperation de l'activité pro
			$activProRow = $bredea->getRow('001factiv', array('act_code' => trim($fdosfa['dosfa_conv_activ'])));
			$activitePro = 	$activProRow ? trim($activProRow['act_code3']) : '';

			// lire infos conjoint
			for ($i = 0; $i < 20; $i++) {
				if (trim($fdosfa['dosfa_membf_'.$i]) == '001') {
					$nom = explode(" ", trim($fdosfa['dosfa_nomf_'.$i]));

					for ($j = 0; $j < count($nom); $j++) {
						if ($j == 0) {
							$conjoint['nom'] = $nom[0];
						} else {
							$conjoint['prenom'] .= ' ' . $nom[$j];
						}
					}

					$dateNaissance = trim($fdosfa['dosfa_dtnaisf_'.$i]);
					$anne_naiss = substr($dateNaissance, -4); // 31122010
					$mois_naiss = substr($dateNaissance, 2, 2);
					$jour_naiss = substr($dateNaissance, 0, 2);
					$conjoint['dateNaissance'] = $anne_naiss.'-'.$mois_naiss.'-'.$jour_naiss;

					$conjoint['sexe'] = trim($fdosfa['dosfa_sexef_'.$i]);
					$conjoint['civilite'] = ($conjoint['sexe'] == 'F') ? 'MME' : 'MON';
				}
			}

			$possede_conjoint = "NON";
			if (count($conjoint) > 0 && $typre == 'FA') {
				$possede_conjoint = "OUI";
			}

			return array(
				'TypeRattachement' => 'CON',
				'NOMNAI' => $conjoint['nom'],
				'NOM' => $conjoint['nom'],
				'PRENOM' => $conjoint['prenom'],
				'DTNAI' => $conjoint['dateNaissance'],
				// 'LOCANAI' => $locataire['lieuNaissance'], // données à saisir à la main
				// 'NATI' => $nationalite, // on n'a pas la nationalité côté Bredea
				'SEXE' => $conjoint['sexe'],
				'QUAL' => $conjoint['civilite'],
				'ACT' => $activitePro,
				// 'DDACT' => "1987-02-01"
				'POSSEDE_CONJOINT' => $possede_conjoint,
			);
		}
	}


	private function constructInfosPersonneRespEnfAutrCAF($fdosfa, $typre, $getDemandePMS = array())
	{
		$enfAutPers = array();


		// lire infos conjoint
		if (count($getDemandePMS) <= 0) {
			for ($i = 0; $i < 20; $i++) {
				$pers = array();

				if (trim($fdosfa['dosfa_membf_'.$i]) != '001'
					&& trim($fdosfa['dosfa_nomf_'.$i]) != ''
				) {
					if (trim($fdosfa['dosfa_membf_'.$i]) == '002') {
						$typePersonne = 'ENF';
					} elseif (trim($fdosfa['dosfa_membf_'.$i]) == '003') {
						$typePersonne = 'AUT';
					}

					$nom = explode(" ", trim($fdosfa['dosfa_nomf_'.$i]));

					for ($j = 0; $j < count($nom); $j++) {
						if ($j == 0) {
							$pers['nom'] = $nom[0];
						} else {
							$pers['prenom'] .= ' ' . $nom[$j];
						}
					}

					$dateNaissance = trim($fdosfa['dosfa_dtnaisf_'.$i]);
					$anne_naiss = substr($dateNaissance, -4); // 31122010
					$mois_naiss = substr($dateNaissance, 2, 2);
					$jour_naiss = substr($dateNaissance, 0, 2);
					$pers['dateNaissance'] = $anne_naiss.'-'.$mois_naiss.'-'.$jour_naiss;

					$pers['sexe'] = trim($fdosfa['dosfa_sexef_'.$i]);
					$pers['civilite'] = $pers['sexe'] == 'F' ? 'MME' : 'MON';

					$enfAutPers[] = array(
						'TypeRattachement' => $typePersonne,
						'NOMNAI' => $pers['nom'],
						'NOM' => $pers['nom'],
						'PRENOM' => $pers['prenom'],
						'DTNAI' => $pers['dateNaissance'],
						// 'LOCANAI' => $locataire['lieuNaissance'], // données à saisir à la main
						// 'NATI' => $nationalite, // on n'a pas la nationalité côté Bredea
						'SEXE' => $pers['sexe'],
						'QUAL' => $pers['civilite'],
						// 'ACT' => $activitePro,
						// 'DDACT' => "1987-02-01"
						// 'POSSEDE_ENFAUTRPERS' => $possede_enfAutr,
						'TYPEPERSENF' => $typePersonne,
					);
				}
			}

			return $enfAutPers;
		} else {
			return array();
		}
	}


	private function constructInfosRefComCAF($locataire, $fdosfa, $fdossi, $typre, $fcdossi, $getDemandePMS = array())
	{
		// echo "<pre>";
		//print_r($fcdossi);
		// echo "</pre>";
		//die();
		$prefix = $typre == 'PA' ? 'dospa' : 'dosfa';
		$caractToReplace = array(".", ",", " ", "/", "-", ":", "*");

		if (count($getDemandePMS) > 0) {
			// mode ceri
			$resident = $getDemandePMS['RESIDENTS'];

			$d = array(
				'NUMTEL' => trim(str_replace($caractToReplace, '', $resident['TEL'])),
				'NUMTEL2' => trim(str_replace($caractToReplace, '', $resident['TEL_MOBILE'])),
				'ADREMEL' => $resident['E_MAIL'],
			);

			// var_dump($d);die();
			return $d;
		}

		return array( 'NUMTEL' => ($typre == 'FA' || $typre == 'PA') ? trim(str_replace($caractToReplace, '', $fdosfa[$prefix.'_tel'])) : trim(str_replace($caractToReplace, '', $fdossi['dossi_tel'])),
			'NUMTEL2' => ($typre == 'FA' || $typre == 'PA') ? trim(str_replace($caractToReplace, '', $fcdossi['0']['c'.$prefix.'_port'])) : trim(str_replace($caractToReplace, '', $fcdossi['0']['cdossi_port'])),
			'ADREMEL' => $locataire->email, // on récupere sur Wheb car données obligatoires dans Wheb
		);
	}

	private function constructSituationFamilleCAF($fdossi, $fdosfa, $typre, $getDemandePMS = array(), $resa)
	{
		$prefix = $typre == 'PA' ? 'dospa' : 'dosfa';
		$sitfam = "";
		$DDSITFAM = "";
		if (count($getDemandePMS) > 0) {
			$sitfam = ""; // a voir dans le futur (n'existe pas encore datant du mail de Samuel 15:19 15/03/21)
			// var_dump("constructSituationFamilleCAF");die();
		} else {
			if ($typre == 'FA' || $typre == 'PA') {
				switch ($fdosfa[$prefix.'_sitfam']) {
					case 'C':
						$sitfam = "CEL";
						break;
					case 'D':
						$sitfam = "DIV";
						break;
					case 'M':
						$sitfam = "MAR";
						break;
					case 'V':
						$sitfam = "VEU";
						break;
					case 'X':
						$sitfam = "VIM";
						break;
				}
			} else {
				switch ($fdossi['dossi_sitfam']) {
					case 'C':
						$sitfam = "CEL";
						break;
					case 'D':
						$sitfam = "DIV";
						break;
					case 'M':
						$sitfam = "MAR";
						break;
					case 'V':
						$sitfam = "VEU";
						break;
					case 'X':
						$sitfam = "VIM";
						break;
				}
			}
		}

		## Voir si DDSITFAM est dans les champs complémentaires (champs_caf, noeuf SituationFamille);
		$bredea	= null;
		if ($resa) {
			$this->initPMS($resa->idApiPms ?: 1, $idResa);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
					$ceri = true;
				}
			}
		}

		$champsCafSituationFamille = $this->getChampsCafTable()->getChampsCafParNoeud('SituationFamille');
		foreach ($champsCafSituationFamille as $champCaf) {
			if ($champCaf->equivalentCAF == 'DDSITFAM') {
				if ($champCaf->sourcePMS == "bredea") {

					if ($champCaf->tablePMS == "001fdossi") {
						$where = array('dossi_site' => $resa->codeSite, 'dossi_typre' => $resa->typre, 'dossi_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fdosfa") {
						$where = array('dosfa_site' => $resa->codeSite, 'dosfa_typre' => $resa->typre, 'dosfa_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fdospa") {
						$where = array('dospa_site' => $resa->codeSite, 'dospa_typre' => $resa->typre, 'dospa_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fcdossi") {
						$where = array('cdossi_site' => $resa->codeSite, 'cdossi_typre' => $resa->typre, 'cdossi_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fcdosfa") {
						$where = array('cdosfa_site' => $resa->codeSite, 'cdosfa_typre' => $resa->typre, 'cdosfa_nodoss' => $resa->numDossier);
					} elseif ($champCaf->tablePMS == "001fcdospa") {
						$where = array('cdospa_site' => $resa->codeSite, 'cdospa_typre' => $resa->typre, 'cdospa_nodoss' => $resa->numDossier);
					}

					$select = $bredea->getRow($champCaf->tablePMS, $where);
					if ($select) {
						if ($champCaf->idType == 2) {
							$jour = substr($select[$champCaf->equivalentPMS], 6, 2);
							$anne = substr($select[$champCaf->equivalentPMS], 0, 4);
							$mois = substr($select[$champCaf->equivalentPMS], 4, 2);
							$val = $anne.'-'.$mois.'-'.$jour;
						} else {
							$val = $select[$champCaf->equivalentPMS];
						}
					}
				} else {
					$val = $champCaf->valeur;
				}

				if ($val) {
					$DDSITFAM = $val;
				}
			}
		}

		return array(
			'SITFAM' => $sitfam,
			'DDSITFAM' =>  $DDSITFAM,
		);
	}

	private function constructInfosLogementCAF($typre, $locataire, $fdossi, $fdosfa, $fcloge, $fcsite, $typre, $idLogement, $getDemandePMS = array(), $resa)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$prefix = $typre == 'PA' ? 'dospa' : 'dosfa';

		if (count($getDemandePMS) > 0) {
			$logement = $getDemandePMS['LOGEMENTS'];
			$sejour = $getDemandePMS['SEJOURS'];
			$resident = $getDemandePMS['RESIDENTS'];
			$mvtsejour = $getDemandePMS['MVT_SEJOURS'];

			$titbail = $resident['CIVILITE'] == "Monsieur" || $resident['CIVILITE'] == "Mr" ? "MON" : "MME";

			$lstMvtSejour = $getDemandePMS['MVT_SEJOURS'];
			usort($lstMvtSejour, function ($a, $b) {
				return (int) $a['NO_MVT_SEJOUR'] < (int) $b['NO_MVT_SEJOUR'];
			});

			$lstMvtSejour = $lstMvtSejour[0];
			// var_dump($lstMvtSejour);
			$NO_LOGEMENT = $lstMvtSejour['NO_LOGEMENT'];
			$logement = $getDemandePMS['LOGEMENTS'][$NO_LOGEMENT];

			$dtconvapl = $logement['L_DATCONV'];
			$numconvapl = $logement['L_NUMCONV'];

			$DDENTLOG = "";
			foreach ($mvtsejour as $key => $value) {
				$DDENTLOG = trim($value['DATE_DEB']) != "" ? date('Y-m-d', strtotime($value['DATE_DEB'])) : "";
			}

			// le type d'occupation est lié à la résidence
			$logementWL = $this->getTableObjet('logements')->select(array('id' => $idLogement))->current();
			$batiment = $this->getTableObjet('batiments')->select(array('id' => $logementWL->idBatiment))->current();
			$residence = $this->getTableObjet('residences')->select(array('id' => $batiment->idResidence))->current();

			$d = array(
				 'DTDEM' => date("Y-m-d"),
				  'SURFTOT' => intval($logement['SURFACE']),
				  'NBCOLO' => 0,
				  'MTLOY' => 0,
				  'MOILOY' => date('Y-m', strtotime($sejour['DATE_DEB'])),
				  'DDBAIL' => date('Y-m-d', strtotime($sejour['DATE_DEB'])),
				  'TITBAIL' => $titbail,
				  'DTCONVAPL' => date('Y-m-d', strtotime($dtconvapl)),
				  'NUMCONVAPL' => $numconvapl,
				  'OCCLOG' => $residence->typeOccupation ? $residence->typeOccupation : "",
				  'FRAISUP' => 'false',
				  'DDENTLOG' => $DDENTLOG,
				  'CODLOC' => $locataire->id,
				  'DECENCLOG' => 'true',
				  'AJOURLOYREMB' => 'true',
			  );

			return $d;
		} else {
			if ($typre == 'FA' || $typre == 'PA') {
				$anne_entree_log = substr($fdosfa[$prefix.'_entins'], 0, 4);
				$mois_entree_log = substr($fdosfa[$prefix.'_entins'], 4, 2);
				$jour_entree_log = substr($fdosfa[$prefix.'_entins'], 6, 2);
				$date_entree_log = $anne_entree_log.'-'.$mois_entree_log.'-'.$jour_entree_log;

				$anne_bail =  substr($fdosfa[$prefix.'_debbail'], 0, 4);
				$mois_bail =  substr($fdosfa[$prefix.'_debbail'], 4, 2);
				$jour_bail =  substr($fdosfa[$prefix.'_debbail'], 6, 2);
			} else {
				$anne_entree_log = substr($fdossi['dossi_entins'], 0, 4);
				$mois_entree_log = substr($fdossi['dossi_entins'], 4, 2);
				$jour_entree_log = substr($fdossi['dossi_entins'], 6, 2);
				$date_entree_log = $anne_entree_log.'-'.$mois_entree_log.'-'.$jour_entree_log;

				$anne_bail =  substr($fdossi['dossi_debbail'], 0, 4);
				$mois_bail =  substr($fdossi['dossi_debbail'], 4, 2);
				$jour_bail =  substr($fdossi['dossi_debbail'], 6, 2);
			}

			$date_bail = $anne_bail.'-'.$mois_bail.'-'.$jour_bail;

			$nbColocataire = $locataire->colocataire == "" ? 0 : $locataire->colocataire;

			$titbail = $locataire->civilite == '1' ? 'MON' : 'MME';

			$surf = "";
			if (count($fcloge) > 0 && (int)$fcloge['clog_surfhab'] > 0) {
				$surf = intval($fcloge['clog_surfhab']);
			}


			$anne_conv = '';
			if ($fcloge['clog_dtconv'] != '0' && !empty($fcloge['clog_dtconv'])) {
				$fcloge['clog_dtconv'] = str_repeat("0", 8 - strlen(trim($fcloge['clog_dtconv']))).$fcloge['clog_dtconv'];
				$anne_conv = substr($fcloge['clog_dtconv'], 0, 4);
				$mois_conv = substr($fcloge['clog_dtconv'], 4, 2);
				$jour_conv = substr($fcloge['clog_dtconv'], 6, 2);
			} else {
				$fcsite['csi_dtconvention'] = str_repeat("0", 8 - strlen(trim($fcsite['csi_dtconvention']))).$fcsite['csi_dtconvention'];
				$anne_conv = substr($fcsite['csi_dtconvention'], 4, 4);
				$mois_conv = substr($fcsite['csi_dtconvention'], 2, 2);
				$jour_conv = substr($fcsite['csi_dtconvention'], 0, 2);
			}

			// $dtconvapl = '';
			// if(!empty($fcsite['csi_dtconvention'])) {
			// 	$anne_conv = substr($fcsite['csi_dtconvention'], 4, 6);
			// 	$mois_conv = substr($fcsite['csi_dtconvention'], 2, 2);
			// 	$jour_conv = substr($fcsite['csi_dtconvention'], 0, 2);
			$dtconvapl = $anne_conv.'-'.$mois_conv.'-'.$jour_conv;
			// }

			$numconvapl = ($fcloge['clog_convent'] != "") ? $fcloge['clog_convent'] : "";
			if (empty($numconvapl)) {
				$numconvapl = trim($fcsite['csi_convention']);
			}

			// $dtconvapl = ($fcloge['clog_dtconv'] != 0) ? $fcloge['clog_dtconv'] : "";
			// $numconvapl = ($fcloge['clog_convent'] != "") ? $fcloge['clog_convent'] : "";
			// $dtconvapl = ($date_conv != '') ? $date_conv : "";
			// $numconvapl = ($fcsite['csi_convention'] != "") ? $fcsite['csi_convention'] : "";
			$MOILOY = $anne_bail.'-'.$mois_bail;

			##Recup modèle facture et loyer de la grille tarifaire
			$bredea	= null;
			$resa = $this->getResaTable()->getResa($resa->id);
			if ($resa) {
				$this->initPMS($resa->idApiPms ?: 1, $idResa);

				## Traitement en fonction du PMS
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				if ($this->pms) {
					if ($this->pms->getClassName() === "Bredea") {
						$bredea	= $this->pms;
					} elseif ($this->pms->getClassName() === "CeriFoyer") {
						## Rien à faire pour l'instant
						$ceri = true;
					}
				}
			}
			$MTLOY = '';
			$numDossier = str_repeat("0", 5 - (int)strlen($resa->numDossier)).$resa->numDossier;
			$wherePFA = array();
			$wherePFA['pfa_fact'] = (strlen(trim($typre)) == 1) ? $typre.' '.$numDossier : $typre.$numDossier;
			$wherePFA['pfa_site'] = $resa->codeSite;
			$pfaRows = $bredea->getRows('001fprepfac', $wherePFA);
			if (!empty($pfaRows)) {
				$MTLOY = trim($pfaRows[0]['pfa_mteuro']);
			}

			// le type d'occupation est lié à la résidence
			$logement = $this->getTableObjet('logements')->select(array('id' => $idLogement))->current();
			$batiment = $this->getTableObjet('batiments')->select(array('id' => $logement->idBatiment))->current();
			$residence = $this->getTableObjet('residences')->select(array('id' => $batiment->idResidence))->current();

			return array(
					  'DTDEM' => date("Y-m-d"),
					  'SURFTOT' => $surf,
					  'NBCOLO' => $nbColocataire,
					  'MTLOY' => $MTLOY,
					  'MOILOY' => $MOILOY,
					  'DDBAIL' => $date_bail,
					  'TITBAIL' => $titbail,
					  'DTCONVAPL' => $dtconvapl,
					  'NUMCONVAPL' => $numconvapl,
					  'OCCLOG' => $residence->typeOccupation ? $residence->typeOccupation : "",
					  'FRAISUP' => 'false',
					  'DDENTLOG' => $date_entree_log,
					  'CODLOC' => $resa->codeSite."_".$resa->numDossier."_".substr($locataire->nom, 0, 4), // codeSite_numDossier_4 premières lettres du nom
					  'DECENCLOG' => 'true',
					  'AJOURLOYREMB' => 'true',
					  // 'CHARGEFAM' => 'false'
					);
		}
	}

	private function constructAdresseLocataireCAF($fdosfa, $fdossi, $typre, $floge, $fcloge, $fsite, $insee_com, $getDemandePMS = array(), $residence = null, $logementWL = null)
	{
		// echo "<pre>";
		// 		print_r($fsite);
		// 		echo "</pre>";
		// 		die();

		if (count($getDemandePMS) > 0) {
			// récupérer le dernier mvt_sejour et ensuite le logement
			$lstMvtSejour = $getDemandePMS['MVT_SEJOURS'];
			usort($lstMvtSejour, function ($a, $b) {
				return (int) $a['NO_MVT_SEJOUR'] < (int) $b['NO_MVT_SEJOUR'];
			});

			$lstMvtSejour = $lstMvtSejour[0];
			$NO_LOGEMENT = $lstMvtSejour['NO_LOGEMENT'];
			$log = $getDemandePMS['LOGEMENTS'][$NO_LOGEMENT];

			$adr = trim($log['ADRESSE1']) . " ". trim($log['ADRESSE2']) . "" . trim($log['ADRESSE3']);
			$d = array(
				// 'NUMVOIE' => $NUMVOIE,
				// 'TYPEVOIE' => 'R',
				'NOMVOIE' => $adr,
				'COMPLIDEADR' => 'LOGEMENT ' . trim($logementWL->numero), // LOGEMENT suivi du numéro du logement occupéoccupé
				'COMPLADR' => trim(utf8_decode($residence->nom)), // le nom de la résidence où loge l'allocataire
				'CODEPOS' => $log['CP'],
				'LOCAADR' => trim($log['VILLE']),
				// 'LIEUDIT' => $locataire['adresse'] ,
				'NUMCOMDOS' => $insee_com,
			);

			// var_dump($d);
			// die();

			return $d;
		} else {
			$unwanted_array = array('Š' => 'S', 'š' => 's', 'Ž' => 'Z', 'ž' => 'z', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E',
							'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ù' => 'U',
							'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'ç' => 'c',
							'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o',
							'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ý' => 'y', 'þ' => 'b', 'ÿ' => 'y');

			$adr =  trim($floge['log_adr1']) != '' ?
						trim($floge['log_adr1'])
						: (
							trim($fsite['si_adr1']) != '' ?
							trim($fsite['si_adr1']) :
							trim($fsite['si_adr2'])
						);

			return array(
			// 'NUMVOIE' => $adresse[0],
			// 'TYPEVOIE' => 'R',
			'NOMVOIE' => strtr($adr, $unwanted_array),
			'COMPLIDEADR' => 'LOGEMENT ' . trim($logementWL->numero), // LOGEMENT suivi du numéro du logement occupé
			'COMPLADR' => trim(utf8_decode($residence->nom)), // le nom de la résidence où loge l'allocataire
			'CODEPOS' => trim($floge['log_cp']) != '' ? trim($floge['log_cp']) : trim($fsite['si_cp']),
			'LOCAADR' => trim($floge['log_ville']) != '' ? trim(utf8_decode($floge['log_ville'])) : trim(utf8_decode($fsite['si_ville'])),
			// 'LIEUDIT' => $locataire['adresse'] ,
			'NUMCOMDOS' => $insee_com,
			);
		}
	}

	private function fillXmlDataCaf($datas)
	{
		$infos_bailleur = $datas['infos_bailleur'];
		$infos_organisme = $datas['infos_organisme'];
		$infos_personneResp = $datas['infos_personneResp'];
		$infos_enfAutPers = $datas['infos_enfAutPers'];

		if (count($datas['infos_personneRespCon'] > 0)) {
			if ($datas['infos_personneRespCon']['POSSEDE_CONJOINT'] == "OUI") {
				$infos_personneRespCon = $datas['infos_personneRespCon'];
			}
		}

		$infos_refCom = $datas['infos_refCom'];
		$infos_situationFamille = $datas['infos_situationFamille'];
		$infos_adresse = $datas['infos_adresse'];
		$infos_logement = $datas['infos_logement'];

		// on echappe car ça appartient aux namespaces globales
		$xml_doc = new \DOMDocument("1.0", "utf-8");

		// ajoute le noeud IDEAL au noeud racine
		$xml_doc->appendChild($IDEAL_NODE = $xml_doc->createElement('IDEAL'));

		/***************************************************************************\
								"BAILLEUR"
		\***************************************************************************/
		//ajouter du noeud "BAILLEUR" au noeud "IDEAL"
		$IDEAL_NODE->appendChild($bailleur_node = $xml_doc->createElement('Bailleur'));

		$bailleur_node->appendChild($xml_doc->createElement('IdentificationNationale', $infos_bailleur['IdentificationNationale']));
		$bailleur_node->appendChild($xml_doc->createElement('RaisonSociale', $infos_bailleur['RaisonSociale']));
		$bailleur_node->appendChild($xml_doc->createElement('IdentificationDemandeBailleur', $infos_bailleur['IdentificationDemandeBailleur']));

		/***************************************************************************\
								"ORGANISME"
		\***************************************************************************/
		// ajoute le noeud "ORGANISME" au noeud racine
		$IDEAL_NODE->appendChild($organisme_node = $xml_doc->createElement('Organisme'));

		// Création des sous noeuds "Organisme"
		$organisme_node->appendChild($xml_doc->createElement('MATRICULE', $infos_organisme['MATRICULE']));
		$organisme_node->appendChild($xml_doc->createElement('CAFDEMANDE', $infos_organisme['CAFDEMANDE']));
		// $organisme_node->appendChild($xml_doc->createElement('CAFORIGINE', $infos_organisme['CAFORIGINE']));
		$organisme_node->appendChild($xml_doc->createElement('IDENTAGENCE', $infos_organisme['IDENTAGENCE']));

		/***************************************************************************\
				  PERSONNERESP "LOC"
		\***************************************************************************/
		$IDEAL_NODE->appendChild($personneResp = $xml_doc->createElement('PersonneResp'));
		$personneResp->setAttribute("TypeRattachement", $infos_personneResp['TypeRattachement']);

		// Création des sous noeuds "PERSONNERESP"
		$personneResp->appendChild($xml_doc->createElement('NOMNAI', $infos_personneResp['NOMNAI']));
		$personneResp->appendChild($xml_doc->createElement('NOM', $infos_personneResp['NOM']));
		$personneResp->appendChild($xml_doc->createElement('PRENOM', $infos_personneResp['PRENOM']));
		$personneResp->appendChild($xml_doc->createElement('DTNAI', $infos_personneResp['DTNAI']));
		// $personneResp->appendChild($xml_doc->createElement('LOCANAI', $infos_personneResp['LOCANAI']));
		$personneResp->appendChild($xml_doc->createElement('NATI', $infos_personneResp['NATI']));
		$personneResp->appendChild($xml_doc->createElement('SEXE', $infos_personneResp['SEXE']));
		$personneResp->appendChild($xml_doc->createElement('QUAL', $infos_personneResp['QUAL']));
		$personneResp->appendChild($xml_doc->createElement('ACT', $infos_personneResp['ACT']));
		$personneResp->appendChild($xml_doc->createElement('DDACT', $infos_personneResp['DDACT']));

		## on complete avec les champs configuré dans système->Ideal caf->champsCaf
		if(!empty($datas['extraData'])) {
			$champsCafResp = $this->getChampsCafTable()->getChampsCafParNoeud('PersonneResp');
			foreach($champsCafResp as $champ) {
				if($champ->equivalentCAF && array_key_exists($champ->equivalentCAF, $datas['extraData'])) {
					$val = $datas['extraData'][$champ->equivalentCAF];
					if($val) {
						$personneResp->appendChild($xml_doc->createElement($champ->equivalentCAF, $val));
					}
				}
			}
		}

		/***************************************************************************\
				  PERSONNERESP "CON"
		\***************************************************************************/
		if (count($datas['infos_personneRespCon']) > 0 && $datas['infos_personneRespCon']['POSSEDE_CONJOINT'] == "OUI") {
			$IDEAL_NODE->appendChild($personneRespCon = $xml_doc->createElement('PersonneResp'));
			$personneRespCon->setAttribute("TypeRattachement", $infos_personneRespCon['TypeRattachement']);

			// Création des sous noeuds "PERSONNERESP"
			$personneRespCon->appendChild($xml_doc->createElement('NOMNAI', $infos_personneRespCon['NOMNAI']));
			$personneRespCon->appendChild($xml_doc->createElement('NOM', $infos_personneRespCon['NOM']));
			$personneRespCon->appendChild($xml_doc->createElement('PRENOM', $infos_personneRespCon['PRENOM']));
			$personneRespCon->appendChild($xml_doc->createElement('DTNAI', $infos_personneRespCon['DTNAI']));
			// $personneResp->appendChild($xml_doc->createElement('LOCANAI', $infos_personneRespCon['LOCANAI']));
			$personneRespCon->appendChild($xml_doc->createElement('NATI', $infos_personneRespCon['NATI']));
			$personneRespCon->appendChild($xml_doc->createElement('SEXE', $infos_personneRespCon['SEXE']));
			$personneRespCon->appendChild($xml_doc->createElement('QUAL', $infos_personneRespCon['QUAL']));
			$personneResp->appendChild($xml_doc->createElement('ACT', $infos_personneRespCon['ACT']));
			// $personneResp->appendChild($xml_doc->createElement('DDACT', $infos_personneRespCon['DDACT']));
		}

		/***************************************************************************\
								"REFERENCESCOMMUNICATION"
		\***************************************************************************/
		$IDEAL_NODE->appendChild($referencesCommunication = $xml_doc->createElement('ReferencesCommunication'));

		$referencesCommunication->appendChild($xml_doc->createElement('NUMTEL', $infos_refCom['NUMTEL']));
		$referencesCommunication->appendChild($xml_doc->createElement('NUMTEL2', $infos_refCom['NUMTEL2']));
		$referencesCommunication->appendChild($xml_doc->createElement('ADREMEL', $infos_refCom['ADREMEL']));

		/***************************************************************************\
								"SITUATION FAMILLE"
		\***************************************************************************/
		$IDEAL_NODE->appendChild($situationFamille = $xml_doc->createElement('SituationFamille'));

		$situationFamille->appendChild($xml_doc->createElement('SITFAM', $infos_situationFamille['SITFAM']));
		$situationFamille->appendChild($xml_doc->createElement('DDSITFAM', $infos_situationFamille['DDSITFAM']));

		/***************************************************************************\
									"ENFANT / AUTRE PERSONNES"
		\***************************************************************************/
		if (count($infos_enfAutPers) > 0) {
			foreach ($infos_enfAutPers as $person) { //pour chaque enfant ou autre personnes
				$IDEAL_NODE->appendChild($enfAutPers = $xml_doc->createElement('EnfAutPers'));

				$enfAutPers->appendChild($xml_doc->createElement('NOMNAI', $person['NOMNAI']));
				$enfAutPers->appendChild($xml_doc->createElement('NOM', $person['NOM']));
				$enfAutPers->appendChild($xml_doc->createElement('PRENOM', $person['PRENOM']));
				$enfAutPers->appendChild($xml_doc->createElement('DTNAI', $person['DTNAI']));
				$enfAutPers->appendChild($xml_doc->createElement('SEXE', $person['SEXE']));
				// $enfAutPers->appendChild($xml_doc->createElement('ACT', $person['ACT']));
				// $enfAutPers->appendChild($xml_doc->createElement('DDACT', $person['DDACT']));
				// $enfAutPers->appendChild($xml_doc->createElement('TYPEPARDEM', $person['TYPEPARDEM'])); // Lien de parenté avec le demandeur
				// $enfAutPers->appendChild($xml_doc->createElement('TYPEPARCON', $person['TYPEPARCON'])); // Lien de parenté avec le conjoint
				// $enfAutPers->appendChild($xml_doc->createElement('DDRATENFAUT', $person['DDRATENFAUT'])); // Date d'arrivée au foyer
				$enfAutPers->appendChild($xml_doc->createElement('TYPEPERSENF', $person['TYPEPERSENF']));
			}
		}

		/***************************************************************************\
								"ADRESSE"
		\***************************************************************************/
		$IDEAL_NODE->appendChild($adresse = $xml_doc->createElement('Adresse'));

		// $adresse->appendChild($xml_doc->createElement('NUMVOIE', $infos_adresse['NUMVOIE']));
		// $adresse->appendChild($xml_doc->createElement('TYPEVOIE', $infos_adresse['TYPEVOIE']));
		$adresse->appendChild($xml_doc->createElement('NOMVOIE', $infos_adresse['NOMVOIE']));
		$adresse->appendChild($xml_doc->createElement('COMPLIDEADR', $infos_adresse['COMPLIDEADR']));
		$adresse->appendChild($xml_doc->createElement('COMPLADR', $infos_adresse['COMPLADR']));
		$adresse->appendChild($xml_doc->createElement('CODEPOS', $infos_adresse['CODEPOS']));
		$adresse->appendChild($xml_doc->createElement('LOCAADR', $infos_adresse['LOCAADR']));
		// $adresse->appendChild($xml_doc->createElement('LIEUDIT', $infos_adresse['LIEUDIT']));
		$adresse->appendChild($xml_doc->createElement('NUMCOMDOS', $infos_adresse['NUMCOMDOS']));

		## on complete avec les champs configuré dans système->Ideal caf->champsCaf
		if(!empty($datas['extraData'])) {
			$champsCafResp = $this->getChampsCafTable()->getChampsCafParNoeud('Adresse');
			foreach($champsCafResp as $champ) {
				if($champ->equivalentCAF && array_key_exists($champ->equivalentCAF, $datas['extraData'])) {
					$val = $datas['extraData'][$champ->equivalentCAF];
					if($val) {
						$adresse->appendChild($xml_doc->createElement($champ->equivalentCAF, $val));
					}
				}
			}
		}

		/***************************************************************************\
								  "LOGEMENT"
		\***************************************************************************/
		$IDEAL_NODE->appendChild($logement = $xml_doc->createElement('Logement'));

		$logement->appendChild($xml_doc->createElement('DTDEM', $infos_logement['DTDEM']));
		$logement->appendChild($xml_doc->createElement('SURFTOT', $infos_logement['SURFTOT']));
		$logement->appendChild($xml_doc->createElement('NBCOLO', $infos_logement['NBCOLO']));
		$logement->appendChild($xml_doc->createElement('MTLOY',$infos_logement['MTLOY']));
		$logement->appendChild($xml_doc->createElement('MOILOY', $infos_logement['MOILOY']));
		$logement->appendChild($xml_doc->createElement('DDBAIL', $infos_logement['DDBAIL']));
		$logement->appendChild($xml_doc->createElement('TITBAIL', $infos_logement['TITBAIL']));
		$logement->appendChild($xml_doc->createElement('DTCONVAPL', $infos_logement['DTCONVAPL']));
		$logement->appendChild($xml_doc->createElement('NUMCONVAPL', $infos_logement['NUMCONVAPL']));
		$logement->appendChild($xml_doc->createElement('OCCLOG', $infos_logement['OCCLOG']));
		$logement->appendChild($xml_doc->createElement('FRAISUP', $infos_logement['FRAISUP']));
		$logement->appendChild($xml_doc->createElement('CODLOC', $infos_logement['CODLOC']));
		$logement->appendChild($xml_doc->createElement('DDENTLOG', $infos_logement['DDENTLOG']));
		$logement->appendChild($xml_doc->createElement('DECENCLOG', $infos_logement['DECENCLOG']));
		$logement->appendChild($xml_doc->createElement('AJOURLOYREMB', $infos_logement['AJOURLOYREMB']));
		// $logement->appendChild($xml_doc->createElement('CHARGEFAM',$infos_logement['CHARGEFAM']));

		## on complete avec les champs configuré dans système->Ideal caf->champsCaf
		if(!empty($datas['extraData'])) {
			$champsCafResp = $this->getChampsCafTable()->getChampsCafParNoeud('Logement');
			foreach($champsCafResp as $champ) {
				if($champ->equivalentCAF && array_key_exists($champ->equivalentCAF, $datas['extraData'])) {
					$val = $datas['extraData'][$champ->equivalentCAF];
					if($val) {
						$logement->appendChild($xml_doc->createElement($champ->equivalentCAF, $val));
					}
				}
			}
		}

		return $xml_doc;
	}

	private function getAllDataCaf($idResa, $insee_com)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$this->getResaTable()->setAdapter($adapter);

		// Reservation
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$logement = $this->getTableObjet('logements')->select(array('id' => $resa->idLogement))->current();
		$batiment = $this->getTableObjet('batiments')->select(array('id' => $logement->idBatiment))->current();
		$residence = $this->getTableObjet('residences')
			->select(array('id' => $batiment->idResidence))->current();

		// Locataire
		$idLocataire = $resa->idLocataire;
		// $locataire = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter);
		$locataire = $this->getTableObjet('locataires')->select(array('id' => $idLocataire))->current();


		// Récuperation du zone_geographique à partir de la nationalite
		$pays = $this->getPaysTable()->getPays($locataire->idNationalite);
		$locataire->zone_geographique = $pays->zone_geographique;

		$bredea		= null;
		if ($resa) {
			$this->initPMS($resa->idApiPms ?: 1, $idResa);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
					$ceri = true;
				}
			}
		}
		if ($ceri) {
			## Création du PMS Generique
			## ~~~~~~~~~~~~~~~~~~~~~~~~~
			try {
				$pmsGen	= new PmsGen($adapter, $resa->idApiPms);
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms ERROR-exception=".$ex->getMessage());

				echo "erreur dans PMsGen Exception=".$ex->getMessage();
				die();
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms=".$pmsGen->shortPrint());

			if (!$pmsGen) {
				## Pas de PMSgen ??
				## ~~~~~~~~~~~~~~~~
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : newPmsGen_$idApiPms Pas de PMSgen ??");
				echo "erreur pas de PMsGen";
				die();
			}

			try {
				$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
				if (is_object($pms)) {
					// var_dump($rows);die();
					## Convertir la réponse à partir du charset de la BDD
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					// mb_convert_variables('UTF-8', 'ISO-8859-1', $rows);

					// $cmd="select NO_ALLOCATAIRE from RESIDENTS WHERE NO_RESIDENT='".$locataire->idPMS."'";
					$getDemandePMS = $pms->getDemandePMS($resa->idPMS);

					// echo "<pre>";
					// var_dump($getDemandePMS['LOGEMENTS']);
					// // var_dump($getDemandePMS);
					// echo "</pre>";
					// die();


					// identification interne
					$idDemandeInterne = "123456789";

					$lstMvtSejour = $getDemandePMS['MVT_SEJOURS'];
					usort($lstMvtSejour, function ($a, $b) {
						return (int) $a['NO_MVT_SEJOUR'] < (int) $b['NO_MVT_SEJOUR'];
					});

					$lstMvtSejour = $lstMvtSejour[0];
					$NO_LOGEMENT = $lstMvtSejour['NO_LOGEMENT'];
					$log = $getDemandePMS['LOGEMENTS'][$NO_LOGEMENT];

					// Récuperation du code organisme caf
					$caf = $this->getCafTable()->fetchAll()->toArray();
					$caf_cp = $this->getCafTable()->getOrganismeByCp(substr($log['CP'], 0, 2));
					$code_caf_demande = $caf_cp->toArray()[0]['code'];

					$organisme = array(
							'matricule' => $getDemandePMS['RESIDENTS']['NO_ALLOCATAIRE'],
							'cafDemande' => $code_caf_demande,
							'cafCodeAgence' => '', // quel champ pour code agence CERI ?
						);

					$infos = array(
							'nom' => $locataire->nom,
							'prenom' => $locataire->prenom,
							'code_caf_demande' => $code_caf_demande,
							// 'code_site_demande' => $resa->codeSite,
							'etat_demande' => 'ouverture',
						);

					$bailleur = array(
							'idNationale' =>  $getDemandePMS['ETABL']['CODE_BAILLEUR'],
							'raisonSociale' => $getDemandePMS['ETABL']['NOM'],
							'idDemandeBailleur' => $idDemandeInterne,
						);

					// echo "<pre>";
					// var_dump($getDemandePMS);
					// echo "</pre>";
					// die();

					$resp = array(
							'infos_bailleur' 		=> $this->constructInfosBailleurCAF($bailleur),
							'infos_organisme' 		=> $this->constructInfosOrganismeCAF($organisme, $getDemandePMS),
							'infos_personneResp' 		=> $this->constructInfosPersonneRespCAF($locataire, null, null, $resa->typre, $getDemandePMS, $resa),
							'infos_personneRespCon' 	=> $this->constructInfosPersonneRespConCAF(null, $resa->typre, $getDemandePMS),
							'infos_refCom' 			=> $this->constructInfosRefComCAF($locataire, null, null, $resa->typre, null, $getDemandePMS),
							'infos_situationFamille' 	=> $this->constructSituationFamilleCAF(null, null, $resa->typre, $getDemandePMS, $resa),
							'infos_enfAutPers' 		=> $this->constructInfosPersonneRespEnfAutrCAF(null, $resa->typre, $getDemandePMS),
							'infos_adresse' 		=> $this->constructAdresseLocataireCAF(null, null, $resa->typre, null, null, null, $insee_com, $getDemandePMS, $residence, $logement),
							'infos_logement' 		=> $this->constructInfosLogementCAF($resa->typre, $locataire, null, null, null, null, $resa->typre, $resa->idLogement, $getDemandePMS, $resa),
						);

					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "IDEAL - getAllDataCaf  ".$dateOperation;
					$log->dataBefore = array();
					$log->dataAfter = $resp;
					$log->tableName = "CF Ceri Foyer";
					$log->idReservation = $resa->id;
					$log->idLocataire = $resa->idLocataire;
					$this->getLogsTable()->saveLogs($log);

					return $resp;

					// echo "\napres importSitesObj_$idApiPms sites="; print_r($rows);
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : pms_$idApiPms connectPms ERROR-exception=".$ex->getMessage());
				echo "erreur dans connectPms Exception=".$ex->getMessage();
				die();
			}
		} elseif ($bredea) {
			##viaPMS $bredea = new BredeaSql();

			if ($resa->typre == 'FA') { // Lire le dossier famille

				$fdosfaWhere = array('dosfa_trait' => 'A', 'dosfa_site' => $resa->codeSite, 'dosfa_typre' => $resa->typre, 'dosfa_nodoss' => $resa->numDossier);
				$fdosfa = $bredea->getRow('001fdosfa', $fdosfaWhere);

				$fcdosfaWhere = array('cdosfa_site' => $resa->codeSite,
									  'cdosfa_nodoss' => $resa->numDossier,
									  'cdosfa_table' => '0');
				$fcdossi = $bredea->getRows('001fcdosfa', $fcdosfaWhere);

				// Logement
				$flogeWhere = array(
										'log_no' => $fdosfa['dosfa_nolog'],
										'log_site' => $fdosfa['dosfa_site'],
								);

				$floge = $bredea->getRow('001floge', $flogeWhere);

				$fclogeWhere = array('clog_no' => $fdosfa['dosfa_nolog'],
									 'clog_sno' => $fdosfa['dosfa_snolog'],
									 'clog_site' => $fdosfa['dosfa_site']);

				$fcloge = $bredea->getRow('001fcloge', $fclogeWhere);
			}elseif ($resa->typre == 'PA') { // Lire le dossier famille

				$fdospaWhere = array('dospa_trait' => 'A', 'dospa_site' => $resa->codeSite, 'dospa_typre' => $resa->typre, 'dospa_nodoss' => $resa->numDossier);
				$fdospa = $bredea->getRow('001fdospa', $fdospaWhere);

				$fcdospaWhere = array('cdospa_site' => $resa->codeSite,
									  'cdospa_nodoss' => $resa->numDossier,
									  'cdospa_table' => '0');
				$fcdossi = $bredea->getRows('001fcdospa', $fcdospaWhere);

				// Logement
				$flogeWhere = array(
										'log_no' => $fdospa['dospa_nolog'],
										'log_site' => $fdospa['dospa_site'],
								);

				$floge = $bredea->getRow('001floge', $flogeWhere);

				$fclogeWhere = array('clog_no' => $fdospa['dospa_nolog'],
									 'clog_sno' => $fdospa['dospa_snolog'],
									 'clog_site' => $fdospa['dospa_site']);

				$fcloge = $bredea->getRow('001fcloge', $fclogeWhere);
			} else {
				//dossier
				$fdossiWhere = array('dossi_trait' => 'A', 'dossi_site' => $resa->codeSite, 'dossi_typre' => $resa->typre, 'dossi_nodoss' => $resa->numDossier);
				$fdossi = $bredea->getRow('001fdossi', $fdossiWhere);

				$fcdossiWhere = array('cdossi_site' => $resa->codeSite,
									  'cdossi_nodoss' => $resa->numDossier,
									  'cdossi_table' => '0');
				$fcdossi = $bredea->getRows('001fcdossi', $fcdossiWhere);

				// logement
				$flogeWhere = array('log_no' => $fdossi['dossi_nolog'],
									'log_site' => $fdossi['dossi_site']);

				$floge = $bredea->getRow('001floge', $flogeWhere);

				$fclogeWhere = array('clog_no' => $fdossi['dossi_nolog'],
									 'clog_sno' => $fdossi['dossi_snolog'],
									 'clog_site' => $fdossi['dossi_site']);

				$fcloge = $bredea->getRow('001fcloge', $fclogeWhere);
			}

			$fclogement = [];
			$flogement = [];
			foreach ($fcloge as $key => $value) {
				$value = trim(utf8_encode($value));
				$fclogement[$key] = $value;
			}

			foreach ($floge as $key => $value) {
				$value = trim(utf8_encode($value));
				$flogement[$key] = $value;
			}

			$scwhere = array('csi_code' => $resa->codeSite);
			$fcsite = $bredea->getRow('001fcsite', $scwhere);

			$sWhere = array('si_code' => $resa->codeSite);
			$fsite = $bredea->getRow('001fsite', $sWhere);
			//print_r($fsite);

			foreach ($fsite as $site => $s) {
				//$fsite[$site] = trim(htmlspecialchars($s,ENT_QUOTES));
				$fsite[$site] = trim(utf8_encode($s));
			}

			// fcdosfa, fcactiv, cdossi
			// $fcactiv = $bredea->getRows('001factiv');
			// var_dump($fcactiv);
			// die();

			// var_dump($fdossi);
			// var_dump($fdosfa);
			// die();

			// Récuperation du code organisme caf
			$caf = $this->getCafTable()->fetchAll()->toArray();
			$caf_cp = $this->getCafTable()->getOrganismeByCp(substr($fsite['si_cp'], 0, 2));
			$code_caf_demande = $caf_cp->toArray()[0]['code'];

			//insertion de la demande et recuperation de l'id demande
			$infos = array('nom' => $locataire->nom,
								'prenom' => $locataire->prenom,
								'code_caf_demande' => $code_caf_demande,
								'code_site_demande' => $resa->codeSite,
								'etat_demande' => 'ouverture');

			// identification interne
			// $idDemandeInterne = "1X2B";
			// identification interne
			$idDemandeInterne = "BAP M ".$fcsite['csi_bailleur']." CODE AGENCE ".$fsite['si_caf'];

			$bailleur = array(
				'idNationale' => $fcsite['csi_bailleur'],
				'raisonSociale' => $fsite['si_nom'],
				'idDemandeBailleur' => $idDemandeInterne
			);

			$organisme = array(
				'matricule' => $fdossi['dossi_noalloc'],
				'cafDemande' => $code_caf_demande,
				'cafCodeAgence' => $fsite['si_caf']
			);

			##Récup infos champs configuré
			$cData = array();
			$cData['locataire'] = $locataire;
			$cData['fdosfa'] = $fdosfa;
			$cData['fdossi'] = $fdossi;
			$cData['fdospa'] = $fdospa;
			$cData['typre'] = $resa->typre;
			$cData['fcdossi'] = $fcdossi;
			$cData['fclogement'] = $fclogement;
			$cData['fcsite'] = $fcsite;
			$cData['sourcePMS'] = 'bredea';
			$extraDataChampsCaf = $this->getDataChampsCaf($cData);

			// DONNEES OBLIGATOIRES A REMPLIR A LA MAIN PAR LE RESPONSABLE :
			// 5 données sensibles =>
			// le Nir,
			// la date d’entrée en France pour les personnes arrivant de l’étranger,
			// le lieu de naissance,
			// le pays d’activité et le régime professionnel.

			// Ces saisies font également l'objet de contrôles de surface : format et présence des données obligatoires.

			## si typre = PA on merge les donnes fdopsa dans fdosfa
			if($resa->typre == 'PA'){
				$fdosfa = $fdospa;
			}

			$resp =  array(
				'infos_bailleur' 		=> $this->constructInfosBailleurCAF($bailleur),
				'infos_organisme' 		=> $this->constructInfosOrganismeCAF($organisme),
				'infos_personneResp' 		=> $this->constructInfosPersonneRespCAF($locataire, $fdosfa, $fdossi, $resa->typre, array(), $resa),
				'infos_personneRespCon' 	=> [],
				'infos_refCom' 			=> $this->constructInfosRefComCAF($locataire, $fdosfa, $fdossi, $resa->typre, $fcdossi),
				'infos_situationFamille' 	=> $this->constructSituationFamilleCAF($fdossi, $fdosfa, $resa->typre, array(), $resa),
				'infos_enfAutPers' 		=> $this->constructInfosPersonneRespEnfAutrCAF($fdosfa, $resa->typre),
				'infos_adresse' 		=> $this->constructAdresseLocataireCAF($fdosfa, $fdossi, $resa->typre, $flogement, $fclogement, $fsite, $insee_com, array(), $residence, $logement),
				'infos_logement' 		=> $this->constructInfosLogementCAF($resa->typre, $locataire, $fdossi, $fdosfa, $fclogement, $fcsite, $resa->typre, $resa->idLogement, array(), $resa),
				);

			if ($resa->typre == 'FA') {
				$resp['infos_personneRespCon'] = $this->constructInfosPersonneRespConCAF($fdosfa, $resa->typre);
			}
			$resp['extraData'] = $extraDataChampsCaf;

			$log = new Logs();
			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = "IDEAL - getAllDataCaf  ".$dateOperation;
			$log->dataBefore = array();
			$log->dataAfter = $resp;
			$log->tableName = "Bredea";
			$log->idReservation = $resa->id;
			$log->idLocataire = $resa->idLocataire;
			$this->getLogsTable()->saveLogs($log);

			$bredea->closeConnect();
			return $resp;
		}
	}

	private function getDataChampsCaf($cData = array())
	{
		$locataire = !empty($cData['locataire']) ? $cData['locataire'] : null;
		$fdosfa = !empty($cData['fdosfa']) ? $cData['fdosfa'] : array();
		$fdossi = !empty($cData['fdossi']) ? $cData['fdossi'] : array();
		$fdospa = !empty($cData['fdospa']) ? $cData['fdospa'] : array();
		$typre = !empty($cData['typre']) ? $cData['typre'] : 'R';
		$fcdossi = !empty($cData['fcdossi']) ? $cData['fcdossi'] : array();
		$fclogement = !empty($cData['fclogement']) ? $cData['fclogement'] : array();
		$fcsite = !empty($cData['fcsite']) ? $cData['fcsite'] : array();
		$sourcePMS = !empty($cData['sourcePMS']) ? $cData['sourcePMS'] : '';
		## recup champs configuré pms
		$dataChampsCaf = array();
		if($sourcePMS) {
			$champsCaf = $this->getChampsCafTable()->getChampsCaf($sourcePMS);
			foreach($champsCaf as $champ) {
				$valeur = null;
				$tablePMS = $champ->tablePMS;
				if($tablePMS == '001fdossi' || $tablePMS == '001fdosfa'  || $tablePMS == '001fdospa' || $tablePMS == '001fcdossi' || $tablePMS == '001fcdosfa' || $tablePMS == '001fcdospa') {
					if($tablePMS == '001fcdossi' || $tablePMS == '001fcdosfa' || $tablePMS == '001fcdospa' ) {
						$dataDossi = $fcdossi;
					} else {
						$dataDossi = $typre == 'FA' ? $fdosfa : $fdossi;
						if($typre == 'PA') $dataDossi = $fdospa;
					}

					if($typre == 'FA') {
						$champ->equivalentPMS = str_replace('dossi_', 'dosfa_', $champ->equivalentPMS);
					}elseif($typre == 'PA'){
						$champ->equivalentPMS = str_replace('dossi_', 'dospa_', $champ->equivalentPMS);
					}
					if(!empty($dataDossi)) {
						if(array_key_exists($champ->equivalentPMS, $dataDossi[0])) {
							$valeur = $dataDossi[0][$champ->equivalentPMS];
							if($champ->idType == 2) {
								if($valeur) {
									$valeur = date('Y-m-d', strtotime($valeur));
								}
							}
						}
					}
				}
				if($valeur && $champ->equivalentCAF) {
					$dataChampsCaf[$champ->equivalentCAF] = $valeur;
				}
			}
		}
		## récup champs avec valerus fixes
		$champsCaf = $this->getChampsCafTable()->getChampsCaf('valeurFixe');
		foreach($champsCaf as $champ) {
			if($champ->valeurFixe && $champ->equivalentCAF) {
				$dataChampsCaf[$champ->equivalentCAF] = $valeur;
			}
		}
		return $dataChampsCaf;
	}

	public function getCafTable()
	{
		if (!$this->cafTable) {
			$sl = $this->getServiceLocator();
			$this->cafTable = $sl->get('Reservation\Model\CafTable');
		}
		return $this->cafTable;
	}
	public function getCafDemandeIdealTable()
	{
		if (!$this->cafDemandeIdealTable) {
			$sl = $this->getServiceLocator();
			$this->cafDemandeIdealTable = $sl->get('Reservation\Model\CafDemandeIdealTable');
		}
		return $this->cafDemandeIdealTable;
	}
	/*******************************************************************************************************\
									FIN	MODULE CAF
	\*******************************************************************************************************/

	/*--------------------------------------- RESSOURCES ------------------------------------*/

	/*
	- Les ressources de l’année N-4 écrasent celles de l’année N-5 (pour les avoir si on l'annuler l'opération de MAJ)
	1. Les ressources de l’année N-3 écrasent celles de l’année N-4
	2. Puis, les ressources de l’année N-2 écrasent celles de l’année N-3
	3. Puis, les ressources de l’année N-1 écrasent celles de l’année N-2
	4. Puis, les ressources de l’année N écrasent celles de l’année N-1
	5. Les champs correspondant aux ressources de l’année N sont vides
	*/
	public function majRessourcesAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$msg = "";
			if (!empty($ids)) {
				$msg = $this->getPLAITable()->majRessourcesParAnneePlus($ids);
			}
			if ($msg == "") {
				$msg = "Mise à jours ressources bien faite";
			}
			$view = new JsonModel(array(
				'success' => true,
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	/*
	1. Les ressources de l’année N-1 sont copiées dans celles de l’année N
	2. Puis, les ressources de l’année N-2 sont copiées dans celles de l’année N-1
	3. Puis, les ressources de l’année N-3 sont copiées dans celles de l’année N-2
	4. Puis, les ressources de l’année N-4 sont copiées dans celles de l’année N-3
	5. Alors, les champs correspondant aux ressources de l’année N-4 sont dans N-5(le champs tmp)
	*/
	public function cancelMajRessourcesAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$msg = "";
			if (!empty($ids)) {
				$msg = $this->getPLAITable()->majRessourcesParAnneeMoins($ids);
			}
			if ($msg == "") {
				$msg = "Annulation mise à jours ressources bien faite";
			}
			$view = new JsonModel(array(
				'success' => true,
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function getPLAITable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		return new PLAITable($adapter);
	}

	public function getSEPATable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->sepaTable) {
			$this->sepaTable = new SEPATable($adapter);
		}
		return $this->sepaTable;
	}

	public function testressAction()
	{
		$ress = $this->getPLAITable()->getRessourcesDeResa(3793);
		//print_r($ress);exit();
		$id = $ress->id;
		$this->getPLAITable()->calculerEtMajDepassement($id);
		$row = $this->getTableObjet('plai_ressources')->select(array('id' => $id))->current();
		print_r($row);
		exit();
	}

	/*------------------------------------- FIN RESSOURCES ----------------------------------*/

	/*------------------------------------- Prestations ----------------------------------*/
	public function loadprestationslisteAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$rows = $this->getPrestaTable()->fetchAllPrestationsCalcules();

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/prestaliste')
			->setVariables(array(
				'rows'	=> $rows,
			));

			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOP,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## affectation prestation au resas
	public function validerPrestationsDeResaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('idsResa', array());
			$idsPresta = $request->getPost('idsPresta', array());
			$dateDebutPF = $request->getPost('dateDebutPF', null);
			$dateFinPF = $request->getPost('dateFinPF', null);
			$msg = "";
			if (!empty($idsResa) && !empty($idsPresta)) {
				$data = array();
				if ($dateDebutPF && $dateFinPF) {
					$data['dateDebutPF'] = $dateDebutPF;
					$data['dateFinPF'] = $dateFinPF;
				}

				$ret = $this->getPrestaTable()->savePrestationsDeResa($idsResa, $idsPresta, $data);
				if (!empty($ret)) {
					$msg = implode('<br>', $ret);
				}
			} else {
				$msg = "Aucune réservation ou prestation choisi";
			}

			$view = new JsonModel(array(
				'success' => true,
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Annulation de calcule de prestations
	public function annulerCalculePrestationsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResaPresta = $request->getPost('ids', array());

			$msg = $msgErrors = "";
			$success = true;

			if (!empty($idsResaPresta)) {
				$ret = $this->getPrestaTable()->annulerCalculePrestations($idsResaPresta);
				if (is_array($ret['error']) && !empty($ret['error'])) {
					$msgErrors .= implode('<br>', $ret['error']);
					if (!empty($ret['error']) && empty($ret['success'])) {
						$success = false;
					}
				}
				if (is_array($ret['success']) && !empty($ret['success'])) {
					$msg .= implode('<br>', $ret['success']);
				}
			} else {
				$msgErrors = "Aucune réservation ou prestation choisi";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'msgErrors' => $msgErrors,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## facturation des prestation affectées
	public function facturerprestationsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResaPresta = $request->getPost('ids', array());
			$etat = $request->getPost('etat');
			$generatePDF = $request->getPost('generatePDF', null);

			$msg = $msgErrors = "";
			$success = true;
			$facturesGenerer = array();
			if (!empty($idsResaPresta) && $etat) {
				//d'abord verification d'existance des prestation par site dans bredea, si oui, continue, sinon arrêter et afficher un msg
				$prestationsParSite = $this->getPrestaTable()->getPrestationsParSiteByIds($idsResaPresta);
				$msgPresta = $this->checkPrestationBredea($prestationsParSite, null, 'parIdApiPms');
				if ($msgPresta == "") {
					$ret = $this->getPrestaTable()->getListePrestationsDeResa($idsResaPresta);
					extract($ret);
					if (!empty($return)) {
						foreach ($return as $idResa => $row) {
							if ($etat == 'facture') {
								$noFact = $this->creerPrestaFacture($idResa);
								if (is_array($noFact)) {
									$msg .= "Erreur :resa $idResa ".implode($noFact)." de ".$row->nomLocataire." ".$row->prenomLocataire;

								} elseif ($noFact) {
									$msg .= "Facture $noFact créée pour résa $idResa de ".$row->nomLocataire." ".$row->prenomLocataire."<br>";
									if ($noFact) {
										$facturesGenerer[] = array('idReservation' => $idResa, 'noFacture' => $noFact);
									}
								} else {
									$msgErrors .= "Erreur création facture pour la résa $idResa de ".$row->nomLocataire." ".$row->prenomLocataire."<br>";
								}
							} elseif ($etat == 'preparationFacture') {
								$this->creerPrestaPreparationFacture($idResa);
								$msg .= "Préparation de facture bien crée du résa $idResa  de ".$row->nomLocataire." ".$row->prenomLocataire."<br>";
							}
						}
					} elseif (empty($errors)) {
						$msgErrors = "Aucune prestation à facturer trouvé";
					}

					if (!empty($errors)) {
						if ($msgErrors) {
							$msgErrors .= "<br>";
						}
						$msgErrors .= implode('<br>', $errors);
					}
				} else {
					$msgErrors = $msgPresta;
					$success = false;
				}
			} else {
				$msgErrors = "Aucune réservation ou prestation choisi";
				$success = false;
			}

			$urlPDF = "";
			if ($generatePDF && $success && !empty($facturesGenerer)) {
				//generer le modele de document des factures générées
				$modele = $this->getTableObjet('type_modeles_docs')->select(array('code' => 'FACT'))->current();
				if ($modele) {
					$urlPDF = $this->genererPdfMergeDocument($facturesGenerer, $modele->id, 'facture');
				}
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'msgErrors' => $msgErrors,
				'urlPDF' => $urlPDF,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	## lancement remboursement des prestations mode Ticket
	public function remboursementprestationsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResaPresta = $request->getPost('ids', array());
			$modeReglement = $request->getPost('modeReglement');//modalité d'encaissement
			$msg = "";
			$success = true;
			$msgErrors = $msgSuccess = "";
			if (!empty($idsResaPresta) && $modeReglement) {

				//on lance que les prestation facturé en mode de paiement Ticket
				$return = $this->getPrestaTable()->lancerRMBDePrestations($idsResaPresta, $modeReglement);

				if (is_array($return['error']) && !empty($return['error'])) {
					$msgErrors = implode('<br>', $return['error']);
				}
				if (is_array($return['success']) && !empty($return['success'])) {
					$msgSuccess = implode('<br>', $return['success']);
				}
			} else {
				$msg = !$modeReglement ? "Aucun mode de réglement choisi" : "Aucune réservation ou modalité choisi";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'msgSuccess' => $msgSuccess,
				'msgErrors' => $msgErrors,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Annulation remboursement des prestations mode Ticket
	public function annulerRemboursementPrestationsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResaPresta = $request->getPost('ids', array());
			$msg = "";
			$success = true;
			$msgErrors = $msgSuccess = "";
			if (!empty($idsResaPresta)) {
				//on le lance que pour les prestation réglé en mode de paiement Ticket
				$return = $this->getPrestaTable()->annulerRMBDePrestations($idsResaPresta);

				if (is_array($return['error']) && !empty($return['error'])) {
					$msgErrors = implode('<br>', $return['error']);
				}
				if (is_array($return['success']) && !empty($return['success'])) {
					$msgSuccess = implode('<br>', $return['success']);
				}
			} else {
				$msg = "Aucune ligne choisi";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'msgSuccess' => $msgSuccess,
				'msgErrors' => $msgErrors,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## chargement des mode de reglement des prestations mode Ticket
	public function loadModesRegPrestaAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResaPresta = $request->getPost('ids', array());

			$msg = "";
			$success = true;
			$options = array();

			if (!empty($idsResaPresta)) {
				//$options = $this->getPrestaTable()->loadModesRegPrestation($idsResaPresta);
				$rows = $this->getTableObjet('modes_paiement')->select();
				foreach ($rows as $row) {
					if ($row->codePMS) {
						$options[$row->codePMS] = $row->nomMode;
					}
				}
			} else {
				$msg = "Aucune réservation ou modalité choisi";
				$success = false;
			}
			if (empty($options)) {
				$msg = "Aucun mode de réglement trouvé, veuillez le configurer dans système";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'options' => $options,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	private function checkPrestationBredea($prestationsParSite = array(), $idApiPms = 1, $mode = '')
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$msg = "";
		if ($conf && $conf->bredea == 1) {
			try {
				if($mode == 'parIdApiPms') {
					if (!empty($prestationsParSite)) {
						$this->pms = null;
						foreach ($prestationsParSite as $idApiPms => $prestationsRows) {
							$bredea		= null;
							$this->initPMS($idApiPms);
							if ($this->pms) {
								if ($this->pms->getClassName() === "Bredea") {
									$bredea	= $this->pms;
								} elseif ($this->pms->getClassName() === "CeriFoyer") {
									## Rien à faire pour l'instant
								}
							} else {
								$msg .= "Erreur initPMS idApiPms=$idApiPms<br>";
							}
							if ($bredea) {
								foreach ($prestationsRows as $site => $prestations) {
									foreach ($prestations as $presCode) {

										if (!$bredea->getPresta($presCode, $site)) {
											$msg .= "La prestation $presCode du site $site n'existe pas pour l'apiPms $idApiPms<br>";
										}
									}
								}
								$this->pms = null;
							}
						}
					} else {
						$msg = "Aucune prestation fournis(dossier absent dans bredea)";
					}
				} else {
					$bredea		= null;
					$this->initPMS($idApiPms);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
					if ($bredea) {
						##viaPMS $bredea = new BredeaSql();
						if (!empty($prestationsParSite)) {
							foreach ($prestationsParSite as $site => $prestations) {
								foreach ($prestations as $presCode) {
									if (!$bredea->getPresta($presCode, $site)) {
										$msg .= "La prestation $presCode du site $site n'existe pas<br>";
									}
								}
							}
						} else {
							$msg = "Aucune prestation fournis(dossier absent dans bredea)";
						}
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				$msg = $ex->getMessage();
			}
		}
		return $msg;
	}

	private function creerPrestaPreparationFacture($idResa, $mode = "prestation", $charges = array(), $idPrestationRegul = 0, $params = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa mode=$mode idPrestationRegul=$idPrestationRegul nb_charges=".count($charges)." 1er=".json_encode(array_slice($charges, 0, 1)));
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$loc =  $this->getLocatairesTable()->getLocataire($resa->idLocataire);
		$conf = $this->getConfigurationTable()->getConfig(1);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$typre = $resa->typre ? $resa->typre : 'R';
		$numDossier = $resa->numDossier ?: $resa->idPMS;
		$codeSite = $resa->codeSite;
		$pasDeFacture = $resa->pasDeFacture;
		$modeCampagne = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
		$nePasAjouterPrestVide = ($modeCampagne && $modeCampagne->nePasAjouterPrestVide == 1) ? true : false;
		if ($conf && $conf->bredea == 1) {
			try {
				if ($resa->idPMS || $resa->numDossier) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					if ($this->pms) {
						$idsCharge = array();
						$idsPrest = array();
						$idsParticipation = array();
						if ($mode == "charge") {
							foreach ($charges as $r) {
								$idsCharge[] = $r->id;
							}
							$AllPrestations = $this->getChargesTable()->getPrestationsDeCharge($idsCharge, 'reparti', $idPrestationRegul, $resa->codeSite);
							if ($AllPrestations && !is_array($AllPrestations)) {
								return array($AllPrestations);
							}
							$prestations = array();
							$montantPresta = 0;
							if ($idPrestationRegul == -1) {
								foreach ($AllPrestations as $p) {
									$p->montantPrestation = $p->montantPrestation;
									$prestations[] = $p;
								}
							} else {
								foreach ($AllPrestations as $p) {
									$montantPresta += $p->montantPrestation;
									$p->montantPrestation = $montantPresta;
									$prestations[0] = $p;
								}
							}
						} elseif ($mode == 'participation') {
							$prestations = !empty($params['prestations']) ? $params['prestations'] : array();
						} else {
							$prestations = $this->getPrestaTable()->getPrestationsDeResa($idResa, 'affecte');
						}

						if (empty($prestations)) {
							return false;
						}

						$options = array();
						//print_r($prestations);exit();
						$montantParticipation = 0;
						$codePrestParticipation = '';
						foreach ($prestations as $prestation) {
							if (($prestation->montantPrestation != 0) || ($mode == "participation")) {
								$lib = $prestation->description;
								if ($prestation->dateDebutPeriode) {
									$lib = $prestation->description.sprintf(" (%s)", substr($prestation->dateDebutPeriode, 0, 4));
								}
								if($nePasAjouterPrestVide && ($prestation->montantPrestation =='' || $prestation->montantPrestation == 0)){
									//ne pas ajouter la prestation
								}else{
									$options['prestationsCalculees'][$prestation->codePMS] = array(		'qte' => 1,
																	'pre_lib' => $lib,
																	'pre_unite' => $prestation->unite,
																	'pre_mteuro' => $prestation->montantPrestation);
								}
							}

							if ($mode == "prestation") {
								$idsPrest[] = $prestation->idPrestaResa;
							} elseif ($mode == "participation") {
								$prestation->dateFacture = $dateFacture;
								$idsParticipation[$prestation->idSuivis.'_'.$prestation->idChamp] = $prestation;
								$montantParticipation += $prestation->montantPrestation;
								if(trim($prestation->codePMS))$codePrestParticipation = trim($prestation->codePMS);
							}
						}
						$loge = $this->getTableObjet('logements')->select(array('id' => $resa->idLogement))->current();
						$modeCamp = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);
						if($modeCamp && $modeCamp->modeAffModeleFacture == 'grilleTarifs') {
							//ne pas maj le loyer
						} else {
							$options['loyer'] = $loge->loyer;
						}

						$prestaLoyerMultiple = array();
						if ($loge && $conf->prestaLoyerMultiple == 1) {
							if ($loge && $conf->prestaLoyerMultiple == 1) {
								$prestaLoyerMultiple = array();
								if ($conf->prestaLoyerHC && $loge->loyerHC > 0) {
									$prestaLoyerMultiple[$conf->prestaLoyerHC] = $loge->loyerHC;
								}
								if ($conf->prestaCharges && $loge->charges > 0) {
									$prestaLoyerMultiple[$conf->prestaCharges] = $loge->charges;
								}
								if ($conf->prestaComplementLoyer && $loge->complementLoyer > 0) {
									$prestaLoyerMultiple[$conf->prestaComplementLoyer] = $loge->complementLoyer;
								}
							}
						}
						$options['prestaLoyerMultiple'] = $prestaLoyerMultiple;
						$options['modeAppel'] = $mode;
						## mode Participation :
						## Si montant = 0 et on a une seule prestation participation, on coche pas de facture
						## Si autre prestations, on décoche  'Pas de facture' quel que soit le montant de la prestation
						if($mode == "participation" && $codePrestParticipation != ''){
							$pasDF =  $this->pms->checkPasDeFacture(array('numDossier'=>$numDossier,'codeSite'=>$codeSite,'typre'=>$resa->typre,'codePrestation'=>$codePrestParticipation,'montantPrestation'=>$montantParticipation));
							if($pasDeFacture != $pasDF){
								$pasDeFacture = $pasDF;
								$this->getTableObjet('reservations')->update(array('pasDeFacture'=>$pasDeFacture),array('id'=>$resa->id));
							}
						}


						$idChargeRegulPMS	= $this->pms->prepFactureDossier($numDossier, $codeSite, $pasDeFacture, 0, $options);
						if($mode == "participation"){
							if(strtoupper(substr($idChargeRegulPMS, 0, 6)) == 'ERREUR') {
								//idChargeRegulPMS dans ce cas reçoit le msg d'erreur
								return array($idChargeRegulPMS);
							}
						}

						if ($mode == "charge" && !empty($idsCharge)) {
							foreach ($idsCharge as $idCharge) {
								$this->getChargesTable()->updateChargeEtat($idCharge, 'preparationFacture');
								if ($idChargeRegulPMS) {
									## Mémorisation de l'id de la demande dans le PMS
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$this->getChargesTable()->updateIdChargeRegulPMS($idCharge, $this->pms->getIdApiPms(), $idChargeRegulPMS);
								}
							}
						}

						if ($mode == "prestation" && !empty($idsPrest)) {
							$this->getPrestaTable()->updateEtatPrestaToResa($idsPrest, 'preparationFacture');
						}

						if ($mode == "participation" && !empty($idsParticipation)) {
							$this->getFormuleExcelTable()->updateEtatPrestaToSuivis($idsParticipation, 'preparationFacture');
						}
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
	}


	## creation facture Prestations
	private function creerPrestaFacture($idResa, $mode = "prestation", $params = array())
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa mode=$mode params=".json_encode($params));
		## type 3 :FDD(facture + encaiss), 4:Caution(encaiss)
		$charges = !empty($params['charges']) ? $params['charges'] : array();
		$idPrestationRegul = !empty($params['idPrestationRegul']) ? $params['idPrestationRegul'] : 0;
		$dateFacture = !empty($params['dateFacture']) ? $params['dateFacture'] : null;

		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$loc =  $this->getLocatairesTable()->getLocataire($resa->idLocataire);
		$conf = $this->getConfigurationTable()->getConfig(1);
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idLogement	= $resa->idLogement;
		if ($idLogement) {
			$logement = $this->getLogementTable()->getResidenceDeLogement($idLogement);
			$idPMSResidence	= $logement->idPMSResidence;
		}
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idLogement=$idLogement idPMSResidence=$idPMSResidence");

		$typre = $resa->typre ? $resa->typre : 'R';
		$noFacture = "";

		if ($conf && $conf->bredea == 1) {
			try {
				if ($resa->idPMS || $resa->numDossier) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						$dataFact = array();
						$dataFact['codeSite'] 	= $resa->codeSite ?: $idPMSResidence;
						$dataFact['numLog'] 	= strtoupper($resa->numeroChambre);
						$dataFact['numDossier']	= $resa->numDossier ?: $resa->idPMS;
						$dataFact['typre']		= $typre;
						$dataFact['dateFact']	= $dateFacture ? date('Ymd', strtotime($dateFacture)) : date('Ymd');
						$dataFact['isRegul']	= "";
						$dataFact['maj_dtderfac']	= "";
						//recup des prestation de la résa
						$idsCharge = array();
						$idsPrest = array();
						$idsParticipation = array();
						if ($mode == "charge") {
							foreach ($charges as $r) {
								$idsCharge[] = $r->id;
							}
							$AllPrestations = $this->getChargesTable()->getPrestationsDeCharge($idsCharge, 'reparti', $idPrestationRegul, $resa->codeSite);

							if ($AllPrestations && !is_array($AllPrestations)) {
								return array($AllPrestations);
							}

							$prestations = array();
							$montantPresta = 0;
							$montant = 0;
							if ($idPrestationRegul == -1) {
								foreach ($AllPrestations as $p) {
									$p->montantPrestation = $p->montantPrestation;
									$prestations[] = $p;
									$montant += $p->montantPrestation;
								}
							} else {
								foreach ($AllPrestations as $p) {
									$montant += $p->montantPrestation;
									$montantPresta += $p->montantPrestation;
									$p->montantPrestation = $montantPresta;
									$prestations[0] = $p;
								}
							}
							$dataFact['isRegul']	= 1;
							$dataFact['montant']	= $montant;
						} elseif ($mode == 'participation' || $mode == 'checkin') {
							$prestations = !empty($params['prestations']) ? $params['prestations'] : array();
						} else {
							$dataFact['maj_dtderfac']	= "1";
							$prestations = $this->getPrestaTable()->getPrestationsDeResa($idResa, 'affecte');
						}

						if (empty($prestations)) {
							return false;
						}
						//print_r($prestations);exit();

						foreach ($prestations as $prestation) {
							if ($prestation->montantPrestation != 0) {
								$lib = $prestation->description;
								if ($prestation->dateDebutPeriode) {
									$lib = $prestation->description.sprintf(" (%s)", substr($prestation->dateDebutPeriode, 0, 4));
								}
								$dataFact['prestCode'][$prestation->codePMS] = array(	'qte' => 1,
															'pre_lib' => $lib,
															'pre_mteuro' => $prestation->montantPrestation);
								if ($mode == "charge") {
									$idsCharge[] = $prestation->idCharge;
								} elseif ($mode == "prestation") {
									$idsPrest[] = $prestation->idPrestaResa;
								} elseif ($mode == "participation") {
									$prestation->dateFacture = $dateFacture;
									$idsParticipation[$prestation->idSuivis.'_'.$prestation->idChamp] = $prestation;
								}
							}
						}

						//print_r($dataFact);exit();
						## on récupére le numéro de la facture qu'on crée
						$noFacture	= $this->pms->creationFacture($dataFact, 'WL');
						if(strtoupper(substr($noFacture, 0, 6)) == 'ERREUR') {
							return false;
						}
						if ($mode == "charge" && $noFacture && !empty($idsCharge)) {
							foreach ($idsCharge as $idCharge) {
								$this->getChargesTable()->updateChargeEtat($idCharge, 'facture');
							}
						}

						if ($mode == "prestation" && $noFacture && !empty($idsPrest)) {
							$this->getPrestaTable()->updateEtatPrestaToResa($idsPrest, 'facture');
						}

						if ($mode == "participation" && $noFacture && !empty($idsParticipation)) {
							$this->getFormuleExcelTable()->updateEtatPrestaToSuivis($idsParticipation, 'facture');
						}

						$log = new Logs();
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "PMS - creation facture $mode $noFacture de ".$loc->nom." ".$loc->prenom;
						$log->dataBefore = array();
						$log->dataAfter = $dataFact;
						$log->tableName = "PMS";
						$log->idReservation = $resa->id;
						$log->idLocataire = $resa->idLocataire;
						$this->getLogsTable()->saveLogs($log);

						$this->pms->closeConnect();
						$this->pms	= null;
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $noFacture;
	}

	public function getPrestaTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->prestaTable) {
			$this->prestaTable = new PrestaTable($adapter);
		}
		return $this->prestaTable;
	}

	/*public function deletepresdoublonAction(){
		$rows = $this->getTableObjet('prestations_to_resa')->select();
		$e = array();
		$i= 0;
		foreach($rows as $row){
			$cle = $row->idReservation.'_'.$row->idPrestation;
			if(array_key_exists($cle,$e)){
				//on supprime
				$this->getTableObjet('prestations_to_resa')->delete(array('id'=>$row->id));
				$i++;
			}else{
				$e[$cle] = $row;
			}
		}
		echo "Terminer $i lignes deleted";

		exit();
	}*/

	public function testprestaAction()
	{
		//$rows = $this->getPrestaTable()->getPrestationsParSiteByIds(array(2,3));
		//print_r($rows);
		//exit();
		//$bredea = new BredeaSql();
		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');

		$where = array();
		$where['hfa_site'] = '01';
		$where['hfa_typre'] = 'FA';
		$where['hfa_dossier'] = '01003';
		$rows = $bredea->getRows('001fhistofac', $where);
		print_r($rows);
		exit();

		$dossierRow = $bredea->getRow('001fdossi', array('dossi_nodoss' => '00364', 'dossi_site' => '05'));
		print_r($dossierRow);
		exit();
		/*$dossierRows = $bredea->getRows('001fdosfa',array('dosfa_trait'=>'A'));
		foreach($dossierRows as $dossier) {

			$numDossier = str_repeat("0",5-(int)strlen($dossier['dosfa_nodoss'])).$dossier['dosfa_nodoss'];
			$resa = $this->getTable('reservations')->select(array('numDossier'=>$numDossier,'codeSite'=>$dossier['dosfa_site'], 'typre' => 'FA'))->current();

			// var_dump($resa);die();
			if($resa && strtotime($resa->dateArrivee) > strtotime('2018-01-01') && $resa->etat ==7) {
				echo $resa->id;exit();
			}
		}*/


		//print_r($bredea->getRows('001fprest',array('pre_site'=>'04')));

		//$bredea->prepFactureDossier('01126','01',0,1,array('loyer'=>555));

		$where = array('pfa_fact' => 'R 01130', 'pfa_site' => '01');
		$rows = $bredea->getRows('001fprepfac', $where);
		print_r($rows);
		$bredea->closeConnect();
		//$this->getPrestaTable()->calculerPrestationsDeResa(2354);
		exit();
		$ret = $this->getPrestaTable()->getPrestationsParSiteByIds(array(1, 2, 3));
		print_r($ret);
		exit();
	}
	/*------------------------------------- FIN Prestations ----------------------------------*/

	/*------------------------------------- charges  ----------------------------------*/
	public function loadCompteurTab($resa)
	{
		if ($resa->idLogement > 0) {
			$rows = $this->getChargesTable()->getCompteursDeLogement($resa->idLogement);
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/fichecompteur')
			->setVariables(array(
				"rows" => $rows,
				"idLogement" => $idLogement,
			));

			$htmlOutput = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);
		} else {
			$htmlOutput = "Pas de logement trouvé";
		}

		return $htmlOutput;
	}

	## facturation de charges réparti
	public function facturerchargesAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsCharges = $request->getPost('ids', array());
			$etat = $request->getPost('etat');
			$idPrestationRegul = $request->getPost('idPrestationRegul', 0);
			$dateFacture = $request->getPost('dateFacture', null);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] etat=$etat idPrestationRegul=$idPrestationRegul dateFacture=$dateFacture idsCharge=".json_encode($idsCharges));
			$msg = "";
			$success = true;
			$facturesGenerer = array();
			if (!empty($idsCharges) && $etat && $idPrestationRegul) {
				//d'abord verification d'existance des prestation par site dans bredea, si oui, continue, sinon arrêter et afficher un msg
				$prestationsParSite = $this->getPrestaTable()->getPrestationsParSiteByResasIds($idsCharges);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] nb_prestationsParSite=".count($prestationsParSite)." 1er=".json_encode(array_slice($prestationsParSite, 0, 1)));
				## ajout option provision par codeCharge
				$prestationParCodeCharge = $this->getChargesTable()->getPrestationsCodeChargeParSite($idsCharges);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] nb_prestationParCodeCharge=".count($prestationParCodeCharge)." 1er=".json_encode(array_slice($prestationParCodeCharge, 0, 1)));

				if (!empty($prestationParCodeCharge)) {
					if (!empty($prestationsParSite)) {
						$prestationsParSite = array_merge($prestationsParSite, $prestationParCodeCharge);
						foreach ($prestationParCodeCharge as $codeSite => $pres) {
							if (array_key_exists($codeSite, $prestationsParSite)) {
								foreach ($pres as $p) {
									$prestationsParSite[$codeSite][] = $p;
								}
							} else {
								foreach ($pres as $p) {
									$prestationsParSite[$codeSite][] = $p;
								}
							}
						}
					} else {
						$prestationsParSite = $prestationParCodeCharge;
					}
				}
				$msgPresta = "";
				//print_r($prestationsParSite);exit();
				if (!empty($prestationsParSite)) {
					$msgPresta = $this->checkPrestationBredea($prestationsParSite);
				}
				if ($msgPresta == "") {
					$return = $this->getChargesTable()->getChargesRepartis($idsCharges);

					if (!empty($return)) {
						$lignesDeChargesParResa = array();//on y stock les charge par résa pour faire un seule facture par résa
						foreach ($return as $idCharge => $row) {
							//on vérifie si la résa est terminé, on la mis en facture pour les prepFacture
							if (0) {
								## Dévalidé par AK après Philanthropique
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								if ($etat == 'preparationFacture' && $row->etatReservation == 6) {
									$etat = 'facture';
								}
							}
							$lignesDeChargesParResa[$row->idReservation][] = $row;
						}
						foreach ($lignesDeChargesParResa as $idResa => $charges) {
							if ($etat == 'facture') {
								$noFact = $this->creerPrestaFacture($idResa, 'charge', array('charges' => $charges, 'idPrestationRegul' => $idPrestationRegul, 'dateFacture' => $dateFacture));
								if (is_array($noFact)) {
									$msg .= "Erreur :resa $idResa ".implode($noFact);
								} else {
									$msg .= "Facture $noFact créée pour résa $idResa<br>";
									if ($noFact) {
										$facturesGenerer[] = array('idReservation' => $idResa, 'noFacture' => $noFact);
									}
								}
								//if($noFact) $facturesGenerer[] = array('idReservation'=>$idResa,'noFacture'=>$noFact);
							} elseif ($etat == 'preparationFacture') {
								$ret = $this->creerPrestaPreparationFacture($idResa, 'charge', $charges, $idPrestationRegul);
								if (is_array($ret)) {
									$msg .= "Erreur :resa $idResa ".implode($ret);
								} else {
									$msg .= "Préparation de facture pour résa $idResa<br>";
								}
							}
						}
					}
				} else {
					$msg = $msgPresta;
					$success = false;
				}
			} elseif (empty($idsCharges)) {
				$msg = "Aucune réservation choisi";
				$success = false;
			} else {
				$msg = "Veuillez choisir une prestation régul par défaut";
				$success = false;
			}

			$urlPDF = "";
			if ($success && !empty($facturesGenerer)) {
				//generer le modele de document des factures générées
				$modele = $this->getTableObjet('type_modeles_docs')->select(array('code' => 'FACT'))->current();
				if ($modele) {
					$urlPDF = $this->genererPdfMergeDocument($facturesGenerer, $modele->id, 'facture');
				}
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'urlPDF' => $urlPDF,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Annulation calcule des charges en etat reparti
	public function annulerCalculeChargeAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsCharges = $request->getPost('ids', array());
			$msg = "";
			if (!empty($idsCharges)) {
				$msg = $this->getChargesTable()->annulerCalculeCharges($idsCharges);
			}
			$view = new JsonModel(array(
				'success' => true,
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function getDateDerniereFactureAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$sites = $request->getPost('sites', array());
			$sites = array_unique($sites);
			$startDate = $endDate = null;
			$monthsDates = $disabledDates = $disabledDates = array();
			if (!empty($sites) && sizeof($sites) == 1) {
				$monthsDates = $this->getChargesTable()->getDateDerniereFacture($sites[0]);
			}
			$now = date('Y-m-d');
			foreach ($monthsDates as $ym => $date) {
				if (!$startDate) {
					$startDate = $date;
				}
				//on disable les dates entre le debut du mois et la date de la derière facture
				$startMonth = date("Y-m-01", strtotime($date));
				$lastDay = date('d', strtotime($date));
				for ($i = 1; $i < $lastDay; $i++) {
					$d = $i;
					if ($i < 10) {
						$d = '0'.$i;
					}
					$disabledDates[] = date('d-m-Y', strtotime($ym.'-'.$d));
				}
			}
			if (!$startMonth) {
				$startDate = date("Y-m-01", strtotime($now));
			}
			/*if(!$startDate){
				//sinon on mets la date du dernier jour de mois passé
				$startDate = date("Y-m-01", strtotime($now));
			}else{
				$endDate = date("Y-m-t", strtotime($startDate));
			}*/

			$view = new JsonModel(array(
				'success' => true,
				'startDate' => date('d-m-Y', strtotime($startDate)),
				//'endDate'=>$endDate ? date('d-m-Y',strtotime($endDate)) : null,
				'endDate' => null,
				'disabledDates' => $disabledDates,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	public function testchargeAction()
	{
		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
		exit();

		//$this->getTableObjet('charges_repartitions')->update(array('etatCharge'=>'reparti'),array('id'=>7227));exit();

		$where = array();
		$where['hfa_site'] = '01';
		$where['hfa_typre'] = 'FA';
		$where['hfa_dossier'] = '01003';
		$where['hfa_nofac'] = 'T110001';
		$rows = $bredea->getRows('001fhistofac', $where);
		//print_r($rows);

		$rows = $bredea->getRows('001fhistorg', array('horg_doss' => '01123', 'horg_site' => '33'));
		print_r($rows);

		$rows = $bredea->getRows('001fhistorg', array('horg_doss' => '00036', 'horg_site' => '73'));
		print_r($rows);
		exit();

		$rows = $bredea->getRows('001fligfac', array('lig_nofac3' => 'T110028', 'lig_dtmaj' => '20201127'));
		print_r($rows);
		exit();

		$set = array(//'dosfa_organ_1' => 'ARI2',
	   // 'dosfa_deborg_1' => '1102013',
		'dosfa_finorg_1' => '12122050');//12122050

		// $bredea->updateRow('001fdosfa',$set,array('dosfa_nodoss'=>'00021','dosfa_site'=>'68'));

		$rows = $bredea->getRow('001fdosfa', array('dosfa_nodoss' => '00021', 'dosfa_site' => '68'));
		print_r($rows);
		exit();

		$whereHistog = array('hgdate1' => '20201126',
							'hgpieces' => '01T110038',
									);
		$histogRows = $bredea->getRows('001histog', $whereHistog);
		print_r($histogRows);
		exit();


		$rows = $this->getTableObjet('charges_repartitions')->select(array('idReservation' => 648))->toArray();
		//$charges = $this->getChargesTable()->getChargesRepartisDeResa(2850);
		//print_r($charges);exit();
		//$resa = $this->getTableObjet('reservations')->select(array('numDossier'=>'01013','codeSite'=>'36'))->current();
		//print_r($resa);
		//$rows = $this->getChargesTable()->getTotalSurfacesTantiemeLogements(3,array(2323,2324,2325,2326));
		//print_r($rows);exit();
		//$this->getTableObjet('charges_repartitions')->delete(array('codeCharge'=>'PF'));
		$rows = $this->getChargesTable()->fetchAllChargesRepartitions();
		print_r($rows);
		exit();
		//print_r($bredea->getRows('001fprest',array('pre_site'=>'36')));exit();
		//$dossiers = $bredea->lireDossiersDePeriode(array('dateDebut'=>'2019-01-01','dateFin'=>'2019-05-31'));
		//print_r($dossiers);
		//exit();
		//$rows = $bredea->getRowTest('001fcloge',$where);//FRPERSO,ORDMENA
		//print_r($rows);
		//exit();
		//$bredea->updateRow('001fparcpt',array('parcpt_cptfin'=>"82019"),array('parcpt_soc'=>'1'));
		//$paramhSite = $bredea->getFparcpt();
		//print_r($paramhSite);exit();

		$rows = $bredea->lirePrestationsProvisoire(array('dateDebut' => '2018-09-01',
														'dateFin' => '2019-05-31',
														'prestaCodes' => array(''),
														));
		print_r($rows);
		$bredea->closeConnect();
		exit();
	}

	public function getChargesTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->chargesTable) {
			$this->chargesTable = new ChargesTable($adapter);
		}
		return $this->chargesTable;
	}
	/*------------------------------------- FIN charges ----------------------------------*/

	//affichage des logements dispo dans la fiche locataire
	public function getLogementsDispo($filtres = array())
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$now = date('Y-m-d');
		if ($filtres['dateDebut'] && strtotime($filtres['dateDebut']) > strtotime($now)) {
			$filtres['dateDebut'] = date('Y-m-d', strtotime($filtres['dateDebut']));
		} else {
			//on cherche depuis la date du jour
			$filtres['dateDebut'] = date('Y-m-d');
		}


		$logementDispo = $this->getLogementTable()->fetchByFiltres(0, $filtres, $conf->mode);

		$logeVilleOptions = array();
		$logeCPOptions = array();

		$idsLogement = array();
		$residenceOptions = array();
		foreach ($logementDispo as $row) {
			$logeAdresse = $row->logeAdresse;
			if($row->noVoie) {
				$logeAdresse = ' - '.$row->noVoie. ' '.$logeAdresse;
			}
			if($row->logeAdresse2) {
				$logeAdresse .= ' '.$row->logeAdresse2;
			}
			if($row->logeAdresse3) {
				$logeAdresse .= ' '.$row->logeAdresse3;
			}
			$idsLogement[$row->id] = $row->nom.' '.$logeAdresse;
			if (!array_key_exists($row->logeVille, $logeVilleOptions)) {
				$logeVilleOptions[$row->logeVille] = $row->logeVille;
			}
			if (!array_key_exists($row->logeCP, $logeCPOptions)) {
				$logeCPOptions[$row->logeCP] = $row->logeCP;
			}
			$residenceOptions[$row->idResidence] = $row->residence;
		}
		asort($idsLogement);
		asort($logeVilleOptions);
		asort($logeCPOptions);
		return array('logementsOptions' => $idsLogement,
					'villesOptions' => $logeVilleOptions,
					'CPOptions' => $logeCPOptions,
					'residenceOptions' => $residenceOptions,
					);
	}


	public function creerFactureFRAIS($idResa, $modeFacture = "")
	{
		$conf = $this->getConfigurationTable()->getConfig(1);

		if (!$idResa) {
			return false;
		}
		$resa = $this->getResaTable()->getResaWithPms($idResa);
		if (!$resa) {
			return false;
		}
		if (!$resa->numDossier) {
			return false;
		}

		$campagneMode = $this->getCampagneTable()->getCampagneMode($resa->idCampagne);

		if ($conf && $conf->bredea == 1) {
			try {
				$bredea		= null;
				if ($resa) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							## Rien à faire pour l'instant
						}
					}
				}
				if ($bredea) {
					$modePaiementCampagne = $this->getModePaiementCampagne($resa->idCampagne);
					## on cree la facture des autre prestation
					$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa));
					$prestations = array();
					$montantPrestations = array();
					$montant = 0;
					foreach ($comptes as $c) {
						if ($c->type == 4) {
							continue;
						}
						if ($campagneMode && $campagneMode->nePasCreerFactureFDD == 1 /*&& $c->type==3*/) {
							continue;
						}
						if ($c->solde > 0 || ($modeFacture == "acompte" && $c->etat == 1)) {
							$typePresation = $this->getTableObjet('type_prestation')->select(array('id' => $c->type))->current();
							if ($typePresation) {
								if ($c->type == 3 && $c->solde == 199) {
									//fdd renouvelenat
									//$typePresation->codePrestation = 'FD2';
								}
								if ($c->type == 9 && $c->solde == 155) {
									//kit couple
									$typePresation->codePrestation = 'KIT1';
								}

								if ($conf->mode == "HEC" && $c->type == 3) {
									if ($c->solde == 110) {
										$typePresation->codePrestation = 'FR02';
									} else {
										$typePresation->codePrestation	= 'FR01';
									}
								}
							}


							if ($c->type == 3 && $modeFacture == "acompte" && ($conf->encaisAcompte == 1 && $conf->prestationFDD || $modePaiementCampagne == 'paiementDirect')) {
								## on recup le montant d'acompte 001facompte : acomp_site, acomp_dossier, acomp_mteuro
								$aCompte = $bredea->getRow('001facompte', array('acomp_site' => $resa->codeSite, 'acomp_dossier' => $resa->numResa));
								if (!empty($aCompte) && !empty($aCompte['acomp_mteuro'])) {
									$c->debit	= $aCompte['acomp_mteuro'];
								}

								//cas paiement des frais via acompte
								$montant += $c->debit;
								if ($conf->encaisAcompte == 1 && $conf->prestationFDD) {
									$prestations[$conf->prestationFDD] = '1';
									$montantPrestations[$conf->prestationFDD] = $c->debit;
								} else {
									$prestations[$typePresation->codePrestation] = '1';
									$montantPrestations[$typePresation->codePrestation] = $c->debit;
								}
							} else {
								$montant += $c->solde;
								$prestations[$typePresation->codePrestation] = '1';
								$montantPrestations[$typePresation->codePrestation] = $c->solde;
							}
						}
					}
					if ($montant != 0) {
						$dataFact = array();
						$dataFact['codeSite'] 	= $resa->codeSite;
						$dataFact['numLog'] 	= strtoupper($resa->numeroChambre);
						$dataFact['numDossier']	= $resa->numDossier;
						$dataFact['typre']		= $resa->typre ? $resa->typre : 'R';
						$dataFact['dateFact']	= date('Ymd');
						$dataFact['prestCode']	= $prestations;
						$dataFact['prestMontant'] = $montantPrestations;
						$dataFact['montant']	= $montant;
						$dataFact['controleDates']	= 'non';

						//$dataFact['delaiPaiement']	= $conf->delaiPaiement;
						//print_r($dataFact);exit();

						## on récupére le numéro de la facture qu'on crée
						$noPiece	= $bredea->creationFacture($dataFact);
						$dataFact['noFacture'] = $noPiece;
						$bredea->closeConnect();
						return $noPiece;
					}
				}
			} catch (\Exception $ex) {
				echo $ex->getMessage();
			}
		}
		return "";
	}



	/**
	* function getFormulairesResaHtml
	*  generer les formulaire resa pour le modele de document
	* @access private
	* @param int $idResa
	*/
	private function getFormulairesResaHtml($idResa = null, $idDp = null, $extraParams = array())
	{
		//$serviceLocatorPlugin = $this->plugin('ServiceLocator');
		$idTypeSuivis = !empty($extraParams['idTypeSuivis']) ? $extraParams['idTypeSuivis'] : null;
		$resa = $dp = null;
		if ($idResa) {
			$resa = $this->getResaTable()->getResa($idResa);
			$idLocataire = $resa->idLocataire;
			$idCampagne = $resa->idCampagne;
		}
		if ($idDp) {
			$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			$idLocataire = $dp->idLocataire;
			$idCampagne = $dp->idCampagne;
		}

		if ((!$resa && !$idDp) || ($resa && !$resa->idCampagne) || ($dp && !$dp->idCampagne)) {
			return "";
		}

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$langue = $translator->getLocale();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		//$locAllInfosDyn = $serviceLocatorPlugin->getReservationLocataireTable()->getAllInfosDynamiqueForListe($resa->idLocataire, $adapter,$idResa);
		//$loc = $serviceLocatorPlugin->getReservationLocataireTable()->getLocataire($resa->idLocataire);

		//$locArray = get_object_vars($loc);
		//$locAllInfosObj = array_merge($locArray,$locAllInfosDyn);
		$locAllInfosObj = $this->getLocataireTable()->getAllInfos($idLocataire, $adapter, true, $idResa, $idDp);
		if ($locAllInfosObj['pays']) {
			$locAllInfosObj['idPays'] = $locAllInfosObj['pays'];
		}//on rempalce l id par la vrai valeur
		if ($locAllInfosObj['nationalite']) {
			$locAllInfosObj['idNationalite'] = $locAllInfosObj['nationalite'];
		}



		$resaArray = array();
		if ($resa) {
			$resaArray = get_object_vars($resa);
			foreach ($resaArray as $k => $v) {
				if (!$v || $v == "") {
					unset($resaArray[$k]);
				}
			}
		}
		$dpArray = array();
		if ($dp) {
			$dpArray = get_object_vars($dp);
			foreach ($dpArray as $k => $v) {
				if (!$v || $v == "") {
					unset($dpArray[$k]);
				}
			}
		}
		$suivisData = array();
		if ($idTypeSuivis) {
			$suivisData = $this->getSuivisTable()->getSuivisAllInfos(null, $adapter, array('idResa' => $idResa, 'idDp' => $idDp, 'idTypeSuivis' => $idTypeSuivis));
		}
		if (!empty($resaArray)) {
			$locAllInfosObj = array_merge($locAllInfosObj, $resaArray);
		}
		if (!empty($dpArray)) {
			$locAllInfosObj = array_merge($locAllInfosObj, $dpArray);
		}
		if (!empty($suivisData)) {
			$locAllInfosObj = array_merge($locAllInfosObj, $suivisData);
		}

		if ($resa) {
			$locAllInfosObj['dateArrivee'] = $resa->dateArrivee ? date('d-m-Y', strtotime($resa->dateArrivee)) : "";
			$locAllInfosObj['dateDepart'] = $resa->dateDepart ? date('d-m-Y', strtotime($resa->dateDepart)) : "";
		}
		$sessData = $locAllInfosObj;

		//types logement
		$typesLogement = array();
		$tlRows = $this->getTableObjet('type_logement')->select(array('deleted' => 0));
		foreach ($tlRows as $tl) {
			$typesLogement[$tl->id] = $langue == "en_US" ? $tl->nomEn : $tl->nom;
		}

		$tableChamps = null;
		if ($idTypeSuivis) {
			$typesSuivis = $this->getListeTypesSuivis();
			$typeSuivis = $typesSuivis[$idTypeSuivis];
			/*$TSObj = new \stdClass();
			$TSObj->id = $idTypeSuivis;
			$TSObj->nom = $typeSuivis;
			$forms = array($TSObj);*/
			$forms = array();
			$sWhere = array('idTypeSuivis' => $idTypeSuivis, 'deleted' => '0');
			if ($idResa) {
				$sWhere['idResa'] = $idResa;
			}
			if ($idDp) {
				$sWhere['idDp'] = $idDp;
			}
			$suivisResult = $this->getTableObjet('suivis')->select($sWhere);
			foreach ($suivisResult as $sr) {
				$sr->nom = $typeSuivis;
				if ($sr->dateCreationSuivis) {
					$sr->nom .= ' du '.date('d/m/Y', strtotime($sr->dateCreationSuivis));
				}
				if ($sr->heureCreationSuivis) {
					$sr->nom .= ' à '.$sr->heureCreationSuivis;
				}
				$forms[] = $sr;
			}
			$tableChamps = $this->getTableObjet('champs_suivis');
		} else {
			$whereForms = array('idCampagne' => $idCampagne, 'idType' => 1);
			$forms = $this->getFormulaireTableModel()->getFrontFormBy($whereForms);
			$tableChamps = $this->getTableObjet('champs_formulaires');
		}

		$formsBloc = array();
		$champRow = array();

		$formsIds = array();
		$formChamps = array();
		$dataExtra = array();

		foreach ($forms as $formRow) {
			$formName = html_entity_decode($translator->translate('frm_'.$formRow->id), ENT_NOQUOTES, "UTF-8");
			if (substr($formName, 0, 3) == 'frm' || $idTypeSuivis) {
				$formName = $formRow->nom;
			}

			$formsIds[$formRow->id] = $formName;

			$champsData = array();
			$cWhere = array('active' => 1, 'acces' => 1);
			$cWhereField = '';
			if ($idTypeSuivis) {
				$cWhereField = 'idTypeSuivis';
				$cWhereValue = $idTypeSuivis;
			} else {
				$cWhereField = 'idFormulaire';
				$cWhereValue = $formRow->id;
			}

			$champs = $tableChamps->select(array($cWhereField => $cWhereValue));

			foreach ($champs as $champ) {
				if ($champ->nature == "texte") {
					continue;
				}
				if (!$idTypeSuivis && !array_key_exists($champ->equivalentSql, $sessData) && $champ->equivalentSql != "idTypeLogement") {
					continue;
				}
				$champRow[$champ->row] = $champ->row;

				$formsBloc[$formRow->id] = $champRow;

				$lmsgid = 'l_'.$champ->name.'_'.$champ->id;
				$imsgid = 'i_'.$champ->name.'_'.$champ->id;

				$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();

				$libelle = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8");

				if (substr($libelle, 0, 1) == 'l' || $idTypeSuivis) {
					$libelle = $champ->libelle;
				}

				if ($idTypeSuivis) {
					if (!empty($sessData['suivis_'.$formRow->id][$champ->equivalentSql])) {
						$value = $sessData['suivis_'.$formRow->id][$champ->equivalentSql];
					} elseif (!empty($sessData[$champ->equivalentSql])) {
						$value = $sessData[$champ->equivalentSql];
					} else {
						$value = "";
					}
				} else {
					$value = !empty($sessData[$champ->equivalentSql]) ? $sessData[$champ->equivalentSql] : "";
				}
				if ($idResa && $champ->equivalentSql == "idTypeLogement") {
					$choixRows = $this->getTableObjet('choix_typelogement')->select(array('idReservation' => $idResa));
					foreach ($choixRows as $cr) {
						$lmsgid = 'l_idTypeLogement_'.$champ->id;
						$libelle = html_entity_decode($translator->translate($lmsgid), ENT_NOQUOTES, "UTF-8")." ".$cr->numero;
						if ($cr->idResidence > 0) {
							$residence = $this->getResidencesTable()->getResidence($cr->idResidence);
							$dataExtra[] = array('libelle' => 'Residence', 'valeur' => $residence->nom, 'type' => 'residence');
						}
						if ($cr->idBatiment) {
							$batiment = $this->getBatimentTable()->getBatiment($cr->idBatiment);
							$dataExtra[] = array('libelle' => 'Batiment', 'valeur' => $batiment->nom, 'type' => 'batiment');
						}
						$dataExtra[] = array('libelle' => $libelle, 'valeur' => $typesLogement[$cr->idTypeLogement], 'type' => '');
						$champsData[$champ->id] = array('libelle' => $libelle, 'valeur' => $typesLogement[$cr->idTypeLogement], 'champ' => $champ);
					}
				} else {
					if ($idTypeSuivis && !$value) {
						continue;
					}
					$champsData[$champ->id] = array('libelle' => $libelle, 'value' => $value, 'champ' => $champ);
				}
			}
			$formChamps[$formRow->id] = $champsData;
		}

		//on recupere le nombre de lignes par formulaire
		$formRows = array();
		foreach ($formsBloc as $idForm => $rowsArr) {
			$maxRows = 1;
			if (!empty($rowsArr)) {
				$maxRows = max($rowsArr);
			}
			$formRows[$idForm] = $maxRows;
		}

		$htmlOP = "";
		$formsArray = array();
		$formsName = array();
		//print_r($formChamps);exit();

		foreach ($formsIds as $idForm => $formName) {
			//$htmlOP .= '<div>'.$formName.'</div>';
			$formsName[$idForm] = $formName;

			if (!empty($formChamps[$idForm])) {
				for ($i = 1;$i <= $formRows[$idForm];$i++) {
					$nbrCols = 0;
					$ligne = array();
					$tailleLigne = array();

					$labelValue = array();

					$champs = $formChamps[$idForm];

					foreach ($champs as $cRow) {
						$champ = $cRow['champ'];
						$libelle = $cRow['libelle'];
						$valeur = $cRow['value'];
						$type = $champ->idType;

						$labelValue[$champ->id] = array('label' => "", 'valeur' => "");

						if ($champ->row == $i) {
							if ($champ->tailleColumn == 2) {
								$tailleDiv = '8';
								$width = '60';
								$nbrCols += 2;
							} elseif ($champ->tailleColumn == 3) {
								$tailleDiv = '12';
								$width = '100';
								$nbrCols += 3;
							} else {
								$tailleDiv = '4';
								$width = '30';
								$nbrCols += 1;
							}


							$classPlus = "";

							if ($type == 4) {
								$html = ''.$valeur. ' : ';
								$labelValue[$champ->id]['label'] = $libelle;
							} else {
								$html = ''.$libelle. ' : ';
								$labelValue[$champ->id]['label'] = $libelle;
							}


							if ($type == 4) {
								/*$html .= '<a href="'.$this->getBaseUrl().'/docs/locataires/'.$loc->id.'/'.$valeur.'" target="_blank">
								<i class="fa fa-eye fa-2x-mini"></i>
								</a>';*/
								if ($valeur) {
									$labelValue[$champ->id]['valeur'] = 'O';
								} else {
									$labelValue[$champ->id]['valeur'] = 'N';
								}
							} elseif ($type == 8) {
								if ($valeur == 1) {
									$html .= 'X';
									$labelValue[$champ->id]['valeur'] = 'X';
								} else {
									$html .= '';
									$labelValue[$champ->id]['valeur'] = '';
								}
							} else {
								if (substr($champ->equivalentSql, 0, -1) == "idTypeLogement" || $champ->equivalentSql == "idTypeLogement") {
									$html = "";
									$choixLog = array();
									foreach ($dataExtra as $row2):
										$tClass = "";
										if ($row2['type'] == "residence") {
											$tClass = "clear-left";
										}
										$html .= ''.$row2['libelle'].' : '.$row2['valeur'].'';
										$choixLog[] = array('label' => $row2['libelle'], 'valeur' => $row2['valeur']);

									endforeach;

									$labelValue[$champ->id] = $choixLog;

									$tailleDiv = '12';
									$width = '100';
									$nbrCols += 3;
									$classPlus = "no-padding";
								} else {
									$html .= $valeur;
									$labelValue[$champ->id]['valeur'] = $valeur;
								}
							}



							$html .= '';

							/*$output = "";


							$output .= '<div class="col-sm-'.$tailleDiv.' '.$classPlus.'" style="width:'.$width.'% ;float:left">';
							$output .= $html;
							$output .= '</div>';*/

							if (substr($champ->equivalentSql, 0, -1) == "idTypeLogement" || $champ->equivalentSql == "idTypeLogement") {
								$ligne[$champ->column] = array('choix' => $choixLog);
							} else {
								$ligne[$champ->column] = array('label' => $labelValue[$champ->id]['label'].' :',
															'valeur' => $labelValue[$champ->id]['valeur']);
							}
							$tailleLigne[$champ->column] = $tailleDiv;
						}//end if
					}//end foreach champ

					ksort($ligne);
					ksort($tailleLigne);
					$totalTaille = 0;
					foreach ($tailleLigne as $key => $value) {
						$totalTaille += (int) $value;
					}
					if ($totalTaille < 12) {
						$reste = 12 - $totalTaille;
						$sm = $reste;

						$totalTailleCols = 0;
						$tailleUnDiv = $formRow->nbrCols == 4 ? 3 : 4;

						for ($j = 1; $j <= 3; $j++) {
							if (!empty($tailleLigne[$j])) {
								$totalTailleCols += $tailleLigne[$j];
							}
							if (!array_key_exists($j, $ligne) && $sm > 0) {
								/*if($reste == 8 and sizeof($ligne) == 1 && !array_key_exists(3, $ligne)){
									$sm=4;
								}*/
								if ($j == 2 && $totalTailleCols > $tailleUnDiv) {
									continue;
								} elseif ($j == 3 && $totalTailleCols > ($tailleUnDiv * 2)) {
									continue;
								}

								$ligne[$j] = '';//'<div class="col-sm-'.$tailleUnDiv.'"></div>';
								$sm -= $tailleUnDiv;
							}
						}
					}
					ksort($ligne);
					$formsArray[$idForm][] = $ligne;
					foreach ($ligne as $key => $val) {
						//$htmlOP .= $val;
					}
				}//end for
				//$htmlOP .= '<hr style="width:100%" />';
			}//end if
		}//end foreach forms

		return array('formsName' => $formsName, 'formsArray' => $formsArray);

		//return $htmlOP;
	}

	public function testcsvAction()
	{
		$header = array('col 1', 'col 2', 'col 3', 'col 4', 'col 5');
		$data = array(
			array(11, 12, 13, 14, 15),
			array(21, 22, 23, 24, 25),
			array(31, 32, 33, 34, 35),
			array(41, 42, 43, 44, 45),
			);
		$this->outputExcel($data, $header, 'liste', true);
		exit();
	}

	public function outputExcel($data, $header, $title = "fichier", $saveFile = false, $modeExport = "standard", $idListe = 0, $typesSuivisInFile = array(), $idsModeleStats = array(), $extraParams = array())
	{
		//set_time_limit(3600);
		$nomListe = !empty($extraParams['nomListe']) ? $extraParams['nomListe'] : '';
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$tools = new Tools();
		$conf = $this->getConfigurationTable()->getConfig(1);
		$horodatage = date('YmdHis');
		require_once getcwd() . '/externalibs/PHPExcel/Classes/PHPExcel.php';
		include_once(getcwd() . '/externalibs/PHPExcel/Classes/PHPExcel/IOFactory.php');
		//require_once getcwd() . '/externalibs/PHPExcel/Classes/PHPExcel_Worksheet_Drawing.php';

		// Pas de logo pour les export de type 'statsListe' ou 'statsListeDP' (cf modedp.js.phtml)
		if ($modeExport == "statsListe" || $modeExport == "statsListeDP" || $modeExport == "statsListeDemandes") {
			$objPHPExcel = new \PhpExcel();
		} else {
			$objReader = \PHPExcel_IOFactory::createReader('Excel5');
			$urlLogo = getcwd().'/public/img/'.$conf->logo;
			$objPHPExcel = $objReader->load(getcwd() . "/externalibs/PHPExcel/templates/listeTemplate.xls");
			$objPHPExcel->getActiveSheet()->setCellValue('D1', \PHPExcel_Shared_Date::PHPToExcel(time()));


			//Ajout logo
			if (file_exists($urlLogo) && $conf->afficherLogoExport == 1) {
				$objDrawing = new \PHPExcel_Worksheet_Drawing();    //create object for Worksheet drawing
				$objDrawing->setName('Logo');        //set name to image
				$objDrawing->setPath($urlLogo);
				$objDrawing->setOffsetX(25);                       //setOffsetX works properly
				$objDrawing->setOffsetY(10);                       //setOffsetY works properly
				$objDrawing->setCoordinates('A1');        //set image to cell
				$objDrawing->setWidth(200);                 //set width, height
				$objDrawing->setHeight(80);

				$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());  //save
			}

			if($nomListe && $conf->afficherTitreListeExport == 1) {
				$objPHPExcel->getActiveSheet()->setCellValue('A1', $nomListe);
			}

			$sharedStyle1 = new \PHPExcel_Style();
			$sharedStyle1->applyFromArray(array(
				'fill' => array(
					'type' => \PHPExcel_Style_Fill::FILL_SOLID,
					'color' => array('rgb' => 'CCCCCC'),
				),
				'borders' => array(
					'bottom' => array('style' => \PHPExcel_Style_Border::BORDER_THIN),
					'right'	=> array('style' => \PHPExcel_Style_Border::BORDER_THIN),
					'top' => array('style' => \PHPExcel_Style_Border::BORDER_THIN),
				),
			));
		}

		//$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(\PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
		$columnLetter = '';

		// Ne pas ajouter la dernière colonne
		$length = count($header);
		$x = 0;

		// Transformer année de fin vide en cette année plus 2 ans pour les stats
		$anneeFin = date('Y', strtotime('+2 years'));
		$dateFin = '31/12/'.$anneeFin;

		$allIdsLoc = array();
		$allIdsDossiers = array();
		$allIdsLoge = array();

		foreach ($header as $colNum => $colName) {
			$x++;
			/*if ($x === $length) {
				break;
			}*/
			$colName = utf8_encode($colName);
			$columnLetter = \PHPExcel_Cell::stringFromColumnIndex($colNum);//recup du lettre du colonne depuis l'index : 0=>A, 1=>B etc
			if ($modeExport == "statsListe" || $modeExport == "statsListeDP" || $modeExport == "statsListeDemandes") {
				$rowNum = 1; // Pas de logo pour les export de type 'statsListe' (cf modedp.js.phtml)
			} else {
				$rowNum = 2;
			}
			$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, $rowNum, $colName);
			$objPHPExcel->getActiveSheet()->getColumnDimension($columnLetter)->setAutoSize(true);
			$rowNumData = $rowNum + 1;
			foreach ($data as $rows) {
				$value = !empty($rows[$colNum]) ? $rows[$colNum] : '';
				$value = utf8_encode($value);
				//on enlève les " au début et fin de la chaine
				if (substr($value, strlen($value) - 1, 1) == '"') {
					$value = substr($value, 0, -1);
				}
				if (substr($value, 0, 1) == '"') {
					$value = substr($value, 1, strlen($value));
				}
				if (!$value) {
					$value = ' ';
				}//eviter d'affiche le texte FAUX
				if ($value == "0000-00-00" || $value == "00-00-0000") {
					$value = " ";
				}

				// Afin de retrouver tous les suivis des usagers
				if ($modeExport == "statsListe" || $modeExport == "listes" || $modeExport == "loge_listes") {
					if (strtolower($colName) == "id réservation" || $tools->removeAccent($colName) == $tools->removeAccent("id reservation")) {
						if($modeExport == "loge_listes"){
							//valeur sous form de idResa_idLogement
							$valArr = explode('_',$value);
							$idR = !empty($valArr[0]) ? $valArr[0] : 0;
							$idL = !empty($valArr[1]) ? $valArr[1] : 0;
							$value = $idR;
							$allIdsDossiers[] = $idR;
							$allIdsLoge[] = $idL;
						}else{
							$allIdsDossiers[] = $value;
						}
					}
				} elseif ($modeExport == "statsListeDP" || $modeExport == "dp_listes") {
					if ($colName == "ID Dossier") {
						$allIdsDossiers[] = $value;
					}
				}


				//changement format de dates en //
				$colNameLower = strtolower($tools->removeAccent($colName));//pour eviter de convertir les numero de chambre en date
				if ($tools->isValideDate($value) && strpos($colNameLower, 'numero') === false) {
					//$value = str_replace('-','/',$value);
					$date = new \DateTime($value);
					//$date = strtotime($value);
					$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, $rowNumData, \PHPExcel_Shared_Date::PHPToExcel($date));
					$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($colNum, $rowNumData)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
					//$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, $rowNumData, $value);
				} else {
					if (strpos($colNameLower, "date") !== false && ($modeExport == "statsListe" || $modeExport == "statsListeDP" || $modeExport == "statsListeDemandes")) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, $rowNumData, $dateFin);
						$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($colNum, $rowNumData)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
					} else {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, $rowNumData, $value);
					}
				}
				$rowNumData++;
			}
		}


		if ($modeExport == "standard") {
			$objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle1, "A2:".$columnLetter.'2');
		} elseif ($modeExport == "statsListeDP" || $modeExport == "statsListe") {
			if (count($idsModeleStats) > 0  && $allIdsDossiers) {
				$stringIdsModeles = '';
				foreach ($idsModeleStats as $keyIdMod => $idMod) {
					if ($keyIdMod == 0) {
						$stringIdsModeles .= $idMod;
					} else {
						$stringIdsModeles .= ','.$idMod;
					}
				}

				$stringChampsName = '';
				$table = $this->getTableObjet('stats_modeles_champs');
				$sql = $table->getSql();
				$select = $table->getSql()->select();
				$select->columns(array(
					'champName',
				));
				$select->where('stats_modeles_champs.table = "champs_formulaires" AND idModele IN ('.$stringIdsModeles.')');
				$select->group('stats_modeles_champs.champName');
				$select->order('stats_modeles_champs.id');
				$resultSet = $table->selectWith($select);
				$champsEnPlus = array();
				foreach ($resultSet as $keyR => $row) {
					$champsEnPlus[] = $row;
					if ($keyR == 0) {
						$stringChampsName .= "'".$row->champName."'";
					} else {
						$stringChampsName .= ",'".$row->champName."'";
					}
				}

				if ($stringChampsName != '') {
					// Ajouter les libelles des champs en plus dans l'entete du csv
					$champsStand = array();
					$champsDyn = array();
					$allNamesChampsDyn = '';
					foreach ($champsEnPlus as $key => $champEnPlus) {
						// Aller chercher un libelle par champ
						$champEP = $this->getTableObjet('champs_formulaires')->select(array('name' => $champEnPlus->champName, 'active' => '1'))->current();

						// Séparer les champs standarts des champs dynamiques pour la lecture des valeurs
						if ($champEP->nature == "standard") {
							$champsStand[] = $champEP;
						} else {
							if (empty($champsDyn)) {
								$allNamesChampsDyn .= "'".$champEnPlus->champName."'";
							} else {
								$allNamesChampsDyn .= ",'".$champEnPlus->champName."'";
							}
							$champsDyn[] = $champEP;
						}
					}

					$colNum++;
					$col = $colNum;

					// Ecrire les libelles des champs standarts puis les champs dynamiques
					foreach ($champsStand as $champStand) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, 1, $champStand->libelle);
						$colNum++;
					}
					foreach ($champsDyn as $champDyn) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, 1, $champDyn->libelle);
						$colNum++;
					}

					// Ecrire les valeurs des champs standarts puis dynmaique
					if ($modeExport == "statsListe" || $modeExport == "statsListeDP") {

						// Partie champs standards
						// Récupérer les valeurs par champ standart
						if (!empty($champsStand)) {
							foreach ($champsStand as $chStand) {
								foreach ($allIdsDossiers as $keyIdR => $idDossier) {
									if ($modeExport == "statsListe") {
										$dossier = $this->getTableObjet('reservations')->select(array('id' => $idDossier))->current();
									} elseif ($modeExport == "statsListeDP") {
										$dossier = $this->getTableObjet('domiciliations')->select(array('id' => $idDossier))->current();
									}
									$loc = $this->getTableObjet('locataires')->select(array('id' => $dossier->idLocataire))->current();

									// Aller chercher dans la table champs pour savoir comment récupérer la valeur de ce champ
									// Prendre en compte le type de champ
									$champTable = $this->getTableObjet('champs')->select(array('equivalentSql' => $chStand->name))->current();

									if ($champTable->table == 'locataires') {
										if ($champTable->sourceListe != '') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $loc[$champTable->equivalentSql]))->current();
											if ($champTable->sourceListe == 'nationalites') {
												$valStand = $valChStand->nationalite;
											} elseif ($champTable->sourceListe == 'pays') {
												$valStand = $valChStand->pays;
											} elseif ($champTable->sourceListe == 'sexe' || $champTable->sourceListe == 'civilite' || $champTable->sourceListe == 'lang' || $champTable->sourceListe == 'departements' || $champTable->sourceListe == 'statut_docs') {
												$valStand = $valChStand->nom;
											} else {
												$valStand = $loc[$champTable->equivalentSql];
											}
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $valStand);
										} else {
											if ($tools->isValideDate($loc[$champTable->equivalentSql])) {
												$date = new \DateTime($loc[$champTable->equivalentSql]);
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $date->format('d/m/Y'));
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $loc[$champTable->equivalentSql]);
											}
										}
									} elseif ($champTable->table == 'reservations') {
										if ($champTable->sourceListe != '') {
											if ($champTable->sourceListe == 'etat_reservation' || $champTable->sourceListe == 'type_logement' || $champTable->sourceListe == 'campagnes' || $champTable->sourceListe == 'statut_docs' || $champTable->sourceListe == 'type_locataires' || $champTable->sourceListe == 'statut_familial') {
												$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
												$valStand = $valChStand->nom;
											} elseif ($champTable->sourceListe == 'user') {
												$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('user_id' => $dossier[$champTable->equivalentSql]))->current();
												$valStand = $valChStand->display_name;
											} elseif ($champTable->sourceListe == 'residences') {
												$sqlResidence = "SELECT residences.nom FROM reservations 
													LEFT JOIN logements ON logements.id = reservations.idLogement
													LEFT JOIN batiments ON batiments.id = logements.idBatiment
													LEFT JOIN residences ON residences.id = batiments.idResidence
													WHERE reservations.id = $idDossier";

												$residence = $adapter->query($sqlResidence, array())->current();
												$valStand = $residence->nom;
											} elseif ($champTable->sourceListe == 'menages') {
												$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
												$valStand = $valChStand->nom;
											} else {
												$valStand = $dossier[$champTable->equivalentSql];
											}
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $valStand);
										} else {
											if ($tools->isValideDate($dossier[$champTable->equivalentSql])) {
												$date = new \DateTime($dossier[$champTable->equivalentSql]);
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $date->format('d/m/Y'));
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												if (strpos($chStand->name, "date") !== false) {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $dateFin);
													$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
												} else {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $dossier[$champTable->equivalentSql]);
												}
											}
										}
									} elseif ($champTable->table == 'domiciliations') {
										if ($champTable->sourceListe != '') {
											if ($champTable->sourceListe == 'domiciliations_etat' || $champTable->sourceListe == 'domiciliations_motif' || $champTable->sourceListe == 'campagnes') {
												$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
												$valStand = $valChStand->nom;
											} elseif ($champTable->sourceListe == 'user') {
												$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('user_id' => $dossier[$champTable->equivalentSql]))->current();
												$valStand = $valChStand->display_name;
											} else {
												$valStand = $dossier[$champTable->equivalentSql];
											}
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $valStand);
										} else {
											if ($tools->isValideDate($dossier[$champTable->equivalentSql])) {
												$date = new \DateTime($dossier[$champTable->equivalentSql]);
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $date->format('d/m/Y'));
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												if (strpos($chStand->name, "date") !== false) {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $dateFin);
													$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
												} else {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $dossier[$champTable->equivalentSql]);
												}
											}
										}
									} elseif ($champTable->code == 'age' && $champTable->equivalentSql == 'age') {
										$dateNaiss = $loc['dateNaissance'];
										if ($dateNaiss && $dateNaiss != '0000-00-00') {
											$today = new \DateTime(date('Y-m-d'));
											$dateFinNaiss = new \DateTime($dateNaiss);
											$difference = $today->diff($dateFinNaiss);
											$age = $difference->format('%y');
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $age);
										}
									}
								}
								$col++;
							}
						}

						// Partie champs dynamiques
						// Chercher les valeurs directement pour gagner du temps d'exécution
						// Commencer par les champs dynamiques, puis finir par les champs dynamiques de type multi select (traitement spécial)
						if (!empty($champsDyn)) {
							foreach ($allIdsDossiers as $keyIdRes => $idDossier) {
								$valsDynResa = array();
								$sqlValsDyn = "SELECT 
										valeurs_dynamiques.id AS idVal,
									 	valeurs_dynamiques.idReservation AS idReservation,
									 	valeurs_dynamiques.idDp AS idDp,
									 	valeurs_dynamiques.valeur AS valeur,
									 	valeurs_select.valeur AS valeurSelect,
									 	user.display_name AS user,
									 	valeurs_dynamiques.idChamp AS idChamp,
									 	champs_formulaires.name AS nameChamp,
									 	champs_formulaires.libelle AS libelleChamp,
									 	champs_formulaires.idType AS idTypeChamp
									 FROM 
								 		valeurs_dynamiques
										LEFT JOIN champs_formulaires ON champs_formulaires.id = valeurs_dynamiques.idChamp";

								if ($extraParams['modeEXT'] == 'EXT' && $extraParams['nomCampagne'] != "" && $extraParams['nomCampagne'] != "DP" && $extraParams['nomCampagne'] != "TOUS_Residents" && $extraParams['nomCampagne'] != "TOUS_Usagers") {
									$sqlValsDyn .= " LEFT JOIN formulaires ON formulaires.id = champs_formulaires.idFormulaire";
									$sqlValsDyn .= " LEFT JOIN campagnes ON campagnes.id = formulaires.idCampagne";
								}

								$sqlValsDyn .= " LEFT JOIN valeurs_select ON CASE WHEN (champs_formulaires.idType = '3') THEN valeurs_dynamiques.valeur = valeurs_select.id END
										LEFT JOIN user ON CASE WHEN (champs_formulaires.sourceListe = 'user') THEN valeurs_dynamiques.valeur = user.user_id END
									WHERE 
								 		valeurs_dynamiques.valeur <> ''
								 		AND valeurs_dynamiques.valeur <> 'Choisissez une valeur'
								 		AND valeurs_dynamiques.valeur IS NOT NULL
								 		AND champs_formulaires.name IN ($allNamesChampsDyn)";

								if ($extraParams['modeEXT'] == 'EXT' && $extraParams['nomCampagne'] != "" && $extraParams['nomCampagne'] != "DP" && $extraParams['nomCampagne'] != "TOUS_Residents" && $extraParams['nomCampagne'] != "TOUS_Usagers") {
									$nomCamp = $extraParams['nomCampagne'];
									$sqlValsDyn .= " AND campagnes.nom LIKE '$nomCamp'";
								}

								if ($modeExport == "statsListe") {
									$sqlValsDyn .= " AND valeurs_dynamiques.idReservation = $idDossier";
								} elseif ($modeExport == "statsListeDP") {
									$sqlValsDyn .= " AND valeurs_dynamiques.idDp = $idDossier";
								}

								$rowsValsDyn = $adapter->query($sqlValsDyn)->execute();
								foreach ($rowsValsDyn as $rowVD) {
									$valsDynResa[$rowVD['nameChamp']] = $rowVD;
								}

								// Ecrire les valeurs
								foreach ($champsDyn as $keyCD => $champDyn) {
									foreach ($valsDynResa as $keyVDR => $valDynR) {
										if ($keyVDR == $champDyn['name']) {
											if ($champDyn['idType'] == '3' && $champDyn['sourceListe'] != '') {
												if ($champDyn['sourceListe'] == 'user') {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, $valDynR['user']);
												} else {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, $valDynR['valeurSelect']);
												}
											} elseif ($champDyn['idType'] == '8') {
												if ($valDynR['valeur'] == '1') {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, 'Oui');
												} else {
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, '');
												}
											} elseif ($champDyn['idType'] == '2') {
												if ($valDynR['valeur'] != '' && $valDynR['valeur'] != '0000-00-00') {
													$date = new \DateTime($valDynR['valeur']);
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, $date->format('d/m/Y'));
													$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col + $keyCD, $keyIdRes + 2)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
												}
											} elseif ($champDyn['idType'] == '18') {
												// Si c'est un champ de type multi liste :
												// Découper la valeur_dynamique, les valeurs sont séparées par des virgules
												// Aller chercher les valeurs une par une dans valeurs_select
												if ($valDynR['valeur'] && $valDynR['valeur'] != '') {
													$valsMultiListe = explode(",", $valDynR['valeur']);
													$valMultiListe = "";
													foreach ($valsMultiListe as $keyVML => $valML) {
														$valMLSelect = $this->getTableObjet('valeurs_select')->select(array('id' => $valML))->current();
														if ($keyVML == 0) {
															$valMultiListe .= $valMLSelect->valeur;
														} else {
															$valMultiListe .= "|".$valMLSelect->valeur;
														}
													}
													$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, $valMultiListe);
												}
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 2, $valDynR['valeur']);
											}
										}
									}
								}
							}
						}
					}
				}
			}

			// Créer les csv des suivis rattachés aux modèles en partant des usagers (idLocataire)
			// Pour chaque type de suivis, créer un fichier CSV d'export
			foreach ($typesSuivisInFile as $key => $typeSuivis) {
				$objPHPExcelS = new \PhpExcel();
				$suivis = array();
				if ($modeExport == "statsListe") {
					foreach ($allIdsDossiers as $key => $idResa) {
						$suivisResa = $this->getTableObjet('suivis')->select(array('idResa' => $idResa, 'idTypeSuivis' => $typeSuivis->id, 'deleted' => '0'))->toArray();
						foreach ($suivisResa as $key => $suiviResa) {
							$suivis[] = $suiviResa;
						}
					}
				} elseif ($modeExport == "statsListeDP") {
					foreach ($allIdsDossiers as $key => $idDp) {
						$suivisDp = $this->getTableObjet('suivis')->select(array('idDp' => $idDp, 'idTypeSuivis' => $typeSuivis->id, 'deleted' => '0'))->toArray();
						foreach ($suivisDp as $key => $suiviDp) {
							$suivis[] = $suiviDp;
						}
					}
				}

				// Commencer par les champs standarts des suivis
				// idSuivi, idDp ou idResa, archive, dateCreationSuivis, heureCreationSuivis, idCreateurSuivis
				$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(0, 1, 'ID Suivi');
				if ($modeExport == "statsListe") {
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(1, 1, 'ID Réservation');
				} elseif ($modeExport == "statsListeDP") {
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(1, 1, 'ID Dossier');
				}
				$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(2, 1, 'Suivi archivé');
				$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(3, 1, 'Date création suivi');
				$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(4, 1, 'Heure création suivi');
				$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(5, 1, 'Créateur du suivi');

				$colNum = 6;

				// Si type de suivi = courriers, rajouté les champs standarts courriers (etatCourrier, dateDistribution)
				if ($typeSuivis->type_suivi == "courriers") {
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(6, 1, 'État du courrier');
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(7, 1, 'Date distribution courrier');
					$colNum = 8;
				}

				$colChampDyn = $colNum;

				// Aller chercher tous les champs du suivi et les mettre sur la première ligne du fichier
				$champsSuivis = $this->getTableObjet('champs_suivis')->select(array('idTypeSuivis' => $typeSuivis->id, 'idType' => ['2', '3', '5', '8', '9', '12', '13', '19']))->toArray();
				foreach ($champsSuivis as $keyChampS => $champS) {
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, 1, $champS['libelle']);
				}

				$rowNum = 2;

				$colonneIDcatalogueAjoutee = false;
				foreach ($suivis as $keyS => $suivi) {
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(0, $rowNum, $suivi['id']);
					if ($modeExport == "statsListe") {
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(1, $rowNum, $suivi['idResa']);
					} elseif ($modeExport == "statsListeDP") {
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(1, $rowNum, $suivi['idDp']);
					}

					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(2, $rowNum, $suivi['archive']);

					// Date de création au format date
					$dateSuiviCrea = new \DateTime($suivi['dateCreationSuivis']);
					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(3, $rowNum, $dateSuiviCrea->format('d/m/Y'));
					$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow(3, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');

					$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(4, $rowNum, $suivi['heureCreationSuivis']);

					$user = $this->getTableObjet('user')->select(array('user_id' => $suivi['idCreateurSuivis']))->current();
					if ($user) {
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(5, $rowNum, $user->display_name);
					} else {
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(5, $rowNum, 'Non renseigné');
					}

					// Si type de suivi = courriers, rajouter les champs standarts courriers (etatCourrier, dateDistribution)
					if ($typeSuivis->type_suivi == "courriers") {
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(6, $rowNum, $suivi['etatCourrier']);

						$dateSuiviDistri = new \DateTime($suivi['dateDistribution']);
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow(7, $rowNum, $dateSuiviDistri->format('d/m/Y'));
						$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow(7, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
					}

					## Si le type_suivi du suivi est de type "participation", chercher les champs du catalogue
					## Faire attention à n'ajouter qu'une seule fois les champs d'un même cataloque
					## Obligé de le faire à ce moment car la liaison avec le catalogue se fait avec l'id du suivi ... pourquoi pas avec le type_suivi ? pas sur de comprendre ...
					$dernierIndexChampCatalogue = 0;
					$cataloguesAjoutes = array();
					if ($typeSuivis->type_suivi == "participation") {
						$catalogueSuivi = $this->getTableObjet('catalogue_suivis')->select(array('idSuivis' => $suivi['id']))->current();

						## Ajouter colonne idCatalogue
						if (!$colonneIDcatalogueAjoutee) {
							$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + 1, 1, 'idCatalogue');
						}
						$colonneIDcatalogueAjoutee = true;
						$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + 1, $rowNum, $catalogueSuivi->idCatalogue);

						if ($catalogueSuivi) {
							$catalogue = $this->getTableObjet('catalogues')->select(array('id' => $catalogueSuivi->idCatalogue, 'archive' => '0', 'deleted' => '0'))->current();
							if ($catalogue) {
								$champsCatalogue = $this->getTableObjet('champs_catalogue')->select(array('idTypeCatalogue' => $catalogue->idTypeCatalogue, 'active' => '1'))->toArray();
								$champsCatalogues[] = 'idCatalogue';
								foreach ($champsCatalogue as $keyChampCataloque => $champCatalogue) {

									## Libelle du champ en haut de colonne si pas déjà écrit
									if (!array_key_exists($catalogue->id, $cataloguesAjoutes)) {
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, 1, $champCatalogue['libelle']);
									}

									## Remplir la valeur des champs en dessous
									$valeurChampCatalogue = $this->getTableObjet('catalogue_values')->select(array('idChamp' => $champCatalogue['id'], 'idCatalogue' => $catalogue->id))->current();
									if ($valeurChampCatalogue && trim($valeurChampCatalogue->valeur) != '') {

										if ($champCatalogue['idType'] == '3' && $champCatalogue['sourceListe'] != '') {
											if ($champCatalogue['sourceListe'] == 'user') {
												$userCatalogue = $this->getTableObjet('user')->select(array('user_id' => $valeurChampCatalogue['valeur']))->current();
												$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, $userCatalogue ? $userCatalogue->display_name : "");
											} else {
												$valeurSelectCatalogue = $this->getTableObjet('valeurs_select')->select(array('id' => $valeurChampCatalogue['valeur']))->current();
												$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, $valeurSelectCatalogue ? $valeurSelectCatalogue->valeur : "");
											}
										} elseif ($champCatalogue['idType'] == '8') {
											if ($valeurChampCatalogue['valeur'] == '1') {
												$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, 'Oui');
											} else {
												$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, 'Non');
											}
										} else {
											if ($tools->isValideDate($valeurChampCatalogue['valeur'])) {
												$date = new \DateTime($valeurChampCatalogue['valeur']);
												$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, $date->format('d/m/Y'));
												$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												if (strpos($colNameLower, "date") !== false) {
													$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, $dateFin);
													$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
												} else {
													$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS + $keyChampCataloque + 2 + $dernierIndexChampCatalogue, $rowNum, $valeurChampCatalogue['valeur']);
												}
											}
										}
									}
								}
								$cataloguesAjoutes[$catalogue->id] = count($champsCatalogue);
								$dernierIndexChampCatalogue = $colChampDyn + $keyChampS + $keyChampCataloque + 2;
							}
						}
					}

					// Aller chercher toutes les valeurs dyn du suivi
					$idSuivi = $suivi['id'];
					$sqlValues = "SELECT 
							suivis_values.id AS idVal,
						 	suivis_values.idSuivis AS idSuivi,
						 	suivis_values.valeur AS valeur,
						 	valeurs_select.valeur AS valeurSelect,
						 	user.display_name AS user,
						 	suivis_values.idChamp AS idChamp
						 FROM 
					 		suivis_values
							LEFT JOIN champs_suivis ON champs_suivis.id = suivis_values.idChamp 
							LEFT JOIN valeurs_select ON CASE WHEN (champs_suivis.idType = '3') THEN suivis_values.valeur = valeurs_select.id END
							 LEFT JOIN user ON CASE WHEN (champs_suivis.sourceListe = 'user') THEN suivis_values.valeur = user.user_id END
						WHERE 
					 		suivis_values.valeur <> ''
					 		AND suivis_values.valeur <> 'Choisissez une valeur'
					 		AND suivis_values.valeur IS NOT NULL
					 		AND champs_suivis.idType IN ('2','3','5','8','9','12','13','19')
					 		AND suivis_values.idSuivis = $idSuivi";

					$rows = $adapter->query($sqlValues)->execute();
					$suiviVals = array();
					foreach ($rows as $row) {
						$suiviVals[$row['idChamp']] = $row;
					}

					foreach ($champsSuivis as $keyChampS => $champS) {
						$colNameLower = strtolower($tools->removeAccent($champS['libelle']));
						foreach ($suiviVals as $key => $suiviVal) {
							if ($key == $champS['id']) {
								if ($champS['idType'] == '3' && $champS['sourceListe'] != '') {
									if ($champS['sourceListe'] == 'user') {
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, $suiviVal['user']);
									} else {
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, $suiviVal['valeurSelect']);
									}
								} elseif ($champS['idType'] == '8') {
									if ($suiviVal['valeur'] == '1') {
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, 'Oui');
									} else {
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, 'Non');
									}
								} else {
									if ($tools->isValideDate($suiviVal['valeur'])) {
										$date = new \DateTime($suiviVal['valeur']);
										$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, $date->format('d/m/Y'));
										$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow($colChampDyn + $keyChampS, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
									} else {
										if (strpos($colNameLower, "date") !== false) {
											$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, $dateFin);
											$objPHPExcelS->getActiveSheet()->getStyleByColumnAndRow($colChampDyn + $keyChampS, $rowNum)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
										} else {
											$objPHPExcelS->getActiveSheet()->setCellValueByColumnAndRow($colChampDyn + $keyChampS, $rowNum, $suiviVal['valeur']);
										}
									}
								}
							}
						}
					}

					$rowNum++;
				}

				$objWriterS = \PHPExcel_IOFactory::createWriter($objPHPExcelS, 'CSV');
				$objWriterS->setDelimiter(';');  // Define delimiter

				if ($extraParams['modeEXT'] == "EXT") {
					$nomFileS = $extraParams['nomCampagne']."_".$typeSuivis->type.".csv";
					$cheminApiStats = $extraParams['cheminApiStats'];
					$cheminCampagne = $extraParams['cheminStatsCampagne'];
					$path = $cheminApiStats.$cheminCampagne;
					$objWriterS->save($path.$nomFileS);
				} else {
					$path = getcwd()."/public/docs/modeles/statsListes/";
					if (!is_dir(getcwd()."/public/docs/modeles/statsListes/statsZip/")) {
						mkdir(getcwd()."/public/docs/modeles/statsListes/statsZip/");
					}
					$objWriterS->save($path."statsZip/".$typeSuivis->type.".csv");
				}
			}
		} elseif ($modeExport == 'listes' || $modeExport == 'dp_listes' || $modeExport == 'loge_listes') {

			## Lire la table listes_champs_ext pour ajouter les champs à extraire
			$champsExtraction = $this->getTableObjet('listes_champs_ext')->select(array('idListe' => $idListe))->toArray();

			if (!empty($champsExtraction)) {
				$stringChampsName = '';
				foreach ($champsExtraction as $keyChExt => $champExtraction) {
					$champExtraction = (object) $champExtraction;
					if ($keyChExt == 0) {
						$stringChampsName .= "'".$champExtraction->champName."'";
					} else {
						$stringChampsName .= ",'".$champExtraction->champName."'";
					}
				}

				if ($stringChampsName != '') {
					// Ajouter les libelles des champs en plus dans l'entete du csv
					$champsStand = array();
					$champsDyn = array();
					$allNamesChampsDyn = '';
					$champsLoge = array();
					foreach ($champsExtraction as $key => $champEnPlus) {
						$champEnPlus = (object) $champEnPlus;
						if($champEnPlus->table == 'champs_formulaires_loge' || $champEnPlus->table == 'formulaires_loge'){
							$champEP = $this->getTableObjet('champs_formulaires_loge')->select(array('name' => $champEnPlus->champName, 'active' => '1'))->current();
							if($champEP){
								$champsLoge[] = $champEP;
							}
						}else{
							// Aller chercher un libelle par champ
							$champEP = $this->getTableObjet('champs_formulaires')->select(array('name' => $champEnPlus->champName, 'active' => '1'))->current();

							// Séparer les champs standarts des champs dynamiques pour la lecture des valeurs
							if ($champEP->nature == "standard") {
								$champsStand[] = $champEP;
							} else {
								if (empty($champsDyn)) {
									$allNamesChampsDyn .= "'".$champEnPlus->champName."'";
								} else {
									$allNamesChampsDyn .= ",'".$champEnPlus->champName."'";
								}
								$champsDyn[] = $champEP;
							}
						}
					}

					// $colNum++;
					$col = $colNum;

					// Ecrire les libelles des champs standarts puis les champs dynamiques
					foreach ($champsStand as $champStand) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, 2, $champStand->libelle);
						$colNum++;
					}
					foreach ($champsDyn as $champDyn) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, 2, $champDyn->libelle);
						$colNum++;
					}

					foreach ($champsLoge as $champLoge) {
						$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($colNum, 2, $champLoge->libelle);
						$colNum++;
					}

					// Partie champs standards
					// Récupérer les valeurs par champ standart
					if (!empty($champsStand)) {
						foreach ($champsStand as $chStand) {
							foreach ($allIdsDossiers as $keyIdR => $idDossier) {
								if ($modeExport == "listes" || $modeExport == "loge_listes") {
									$dossier = $this->getTableObjet('reservations')->select(array('id' => $idDossier))->current();
								} elseif ($modeExport == "dp_listes") {
									$dossier = $this->getTableObjet('domiciliations')->select(array('id' => $idDossier))->current();
								}
								$loc = $this->getTableObjet('locataires')->select(array('id' => $dossier->idLocataire))->current();

								// Aller chercher dans la table champs pour savoir comment récupérer la valeur de ce champ
								// Prendre en compte le type de champ
								$champTable = $this->getTableObjet('champs')->select(array('equivalentSql' => $chStand->name))->current();

								if ($champTable->table == 'locataires') {
									if ($champTable->sourceListe != '') {
										$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $loc[$champTable->equivalentSql]))->current();
										if ($champTable->sourceListe == 'nationalites') {
											$valStand = $valChStand->nationalite;
										} elseif ($champTable->sourceListe == 'pays') {
											$valStand = $valChStand->pays;
										} elseif ($champTable->sourceListe == 'sexe' || $champTable->sourceListe == 'civilite' || $champTable->sourceListe == 'lang' || $champTable->sourceListe == 'departements' || $champTable->sourceListe == 'statut_docs') {
											$valStand = $valChStand->nom;
										} else {
											$valStand = $loc[$champTable->equivalentSql];
										}
										$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $valStand);
									} else {
										if ($tools->isValideDate($loc[$champTable->equivalentSql])) {
											$date = new \DateTime($loc[$champTable->equivalentSql]);
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $date->format('d/m/Y'));
											$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
										} else {
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $loc[$champTable->equivalentSql]);
										}
									}
								} elseif ($champTable->table == 'reservations') {
									if ($champTable->sourceListe != '') {
										if ($champTable->sourceListe == 'etat_reservation' || $champTable->sourceListe == 'type_logement' || $champTable->sourceListe == 'campagnes' || $champTable->sourceListe == 'statut_docs' || $champTable->sourceListe == 'type_locataires' || $champTable->sourceListe == 'statut_familial') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
											$valStand = $valChStand->nom;
										} elseif ($champTable->sourceListe == 'user') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('user_id' => $dossier[$champTable->equivalentSql]))->current();
											$valStand = $valChStand->display_name;
										} elseif ($champTable->sourceListe == 'residences') {
											$sqlResidence = "SELECT residences.nom FROM reservations 
												LEFT JOIN logements ON logements.id = reservations.idLogement
												LEFT JOIN batiments ON batiments.id = logements.idBatiment
												LEFT JOIN residences ON residences.id = batiments.idResidence
												WHERE reservations.id = $idDossier";

											$residence = $adapter->query($sqlResidence, array())->current();
											$valStand = $residence->nom;
										} elseif ($champTable->sourceListe == 'menages') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
											$valStand = $valChStand->nom;
										} else {
											$valStand = $dossier[$champTable->equivalentSql];
										}
										$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $valStand);
									} else {
										if ($tools->isValideDate($dossier[$champTable->equivalentSql])) {
											$date = new \DateTime($dossier[$champTable->equivalentSql]);
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $date->format('d/m/Y'));
											$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
										} else {
											if (strpos($chStand->name, "date") !== false) {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $dateFin);
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $dossier[$champTable->equivalentSql]);
											}
										}
									}
								} elseif ($champTable->table == 'domiciliations') {
									if ($champTable->sourceListe != '') {
										if ($champTable->sourceListe == 'domiciliations_etat' || $champTable->sourceListe == 'domiciliations_motif' || $champTable->sourceListe == 'campagnes') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('id' => $dossier[$champTable->equivalentSql]))->current();
											$valStand = $valChStand->nom;
										} elseif ($champTable->sourceListe == 'user') {
											$valChStand = $this->getTableObjet($champTable->sourceListe)->select(array('user_id' => $dossier[$champTable->equivalentSql]))->current();
											$valStand = $valChStand->display_name;
										} else {
											$valStand = $dossier[$champTable->equivalentSql];
										}
										$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $valStand);
									} else {
										if ($tools->isValideDate($dossier[$champTable->equivalentSql])) {
											$date = new \DateTime($dossier[$champTable->equivalentSql]);
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $date->format('d/m/Y'));
											$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
										} else {
											if (strpos($chStand->name, "date") !== false) {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $dateFin);
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $dossier[$champTable->equivalentSql]);
											}
										}
									}
								} elseif ($champTable->code == 'age' && $champTable->equivalentSql == 'age') {
									$dateNaiss = $loc['dateNaissance'];
									if ($dateNaiss && $dateNaiss != '0000-00-00') {
										$today = new \DateTime(date('Y-m-d'));
										$dateFinNaiss = new \DateTime($dateNaiss);
										$difference = $today->diff($dateFinNaiss);
										$age = $difference->format('%y');
										$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 2, $age);
									}
								}
							}
							$col++;
						}
					}

					// // Partie champs dynamiques
					// // Chercher les valeurs directement pour gagner du temps d'exécution
					// // Commencer par les champs dynamiques, puis finir par les champs dynamiques de type multi select (traitement spécial)
					if (!empty($champsDyn)) {
						foreach ($allIdsDossiers as $keyIdRes => $idDossier) {
							$valsDynResa = array();
							$sqlValsDyn = "SELECT 
									valeurs_dynamiques.id AS idVal,
								 	valeurs_dynamiques.idReservation AS idReservation,
								 	valeurs_dynamiques.idDp AS idDp,
								 	valeurs_dynamiques.valeur AS valeur,
								 	valeurs_select.valeur AS valeurSelect,
								 	user.display_name AS user,
								 	valeurs_dynamiques.idChamp AS idChamp,
								 	champs_formulaires.name AS nameChamp,
								 	champs_formulaires.libelle AS libelleChamp,
								 	champs_formulaires.idType AS idTypeChamp
								 FROM 
							 		valeurs_dynamiques
									LEFT JOIN champs_formulaires ON champs_formulaires.id = valeurs_dynamiques.idChamp";

							if ($extraParams['modeEXT'] == 'EXT' && $extraParams['nomCampagne'] != "" && $extraParams['nomCampagne'] != "DP" && $extraParams['nomCampagne'] != "TOUS_Residents" && $extraParams['nomCampagne'] != "TOUS_Usagers") {
								$sqlValsDyn .= " LEFT JOIN formulaires ON formulaires.id = champs_formulaires.idFormulaire";
								$sqlValsDyn .= " LEFT JOIN campagnes ON campagnes.id = formulaires.idCampagne";
							}

							$sqlValsDyn .= " LEFT JOIN valeurs_select ON CASE WHEN (champs_formulaires.idType = '3') THEN valeurs_dynamiques.valeur = valeurs_select.id END
									LEFT JOIN user ON CASE WHEN (champs_formulaires.sourceListe = 'user') THEN valeurs_dynamiques.valeur = user.user_id END
								WHERE 
							 		valeurs_dynamiques.valeur <> ''
							 		AND valeurs_dynamiques.valeur <> 'Choisissez une valeur'
							 		AND valeurs_dynamiques.valeur IS NOT NULL
							 		AND champs_formulaires.name IN ($allNamesChampsDyn)";

							if ($extraParams['modeEXT'] == 'EXT' && $extraParams['nomCampagne'] != "" && $extraParams['nomCampagne'] != "DP" && $extraParams['nomCampagne'] != "TOUS_Residents" && $extraParams['nomCampagne'] != "TOUS_Usagers") {
								$nomCamp = $extraParams['nomCampagne'];
								$sqlValsDyn .= " AND campagnes.nom LIKE '$nomCamp'";
							}

							if ($modeExport == "listes" || $modeExport == "loge_listes") {
								$sqlValsDyn .= " AND valeurs_dynamiques.idReservation = $idDossier";
							} elseif ($modeExport == "dp_listes") {
								$sqlValsDyn .= " AND valeurs_dynamiques.idDp = $idDossier";
							}

							$rowsValsDyn = $adapter->query($sqlValsDyn)->execute();
							foreach ($rowsValsDyn as $rowVD) {
								$valsDynResa[$rowVD['nameChamp']] = $rowVD;
							}

							// Ecrire les valeurs
							foreach ($champsDyn as $keyCD => $champDyn) {
								foreach ($valsDynResa as $keyVDR => $valDynR) {
									if ($keyVDR == $champDyn['name']) {
										if ($champDyn['idType'] == '3' && $champDyn['sourceListe'] != '') {
											if ($champDyn['sourceListe'] == 'user') {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, $valDynR['user']);
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, $valDynR['valeurSelect']);
											}
										} elseif ($champDyn['idType'] == '8') {
											if ($valDynR['valeur'] == '1') {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, 'Oui');
											} else {
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, '');
											}
										} elseif ($champDyn['idType'] == '2') {
											if ($valDynR['valeur'] != '' && $valDynR['valeur'] != '0000-00-00') {
												$date = new \DateTime($valDynR['valeur']);
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, $date->format('d/m/Y'));
												$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col + $keyCD, $keyIdRes + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
											}
										} elseif ($champDyn['idType'] == '18') {
											// Si c'est un champ de type multi liste :
											// Découper la valeur_dynamique, les valeurs sont séparées par des virgules
											// Aller chercher les valeurs une par une dans valeurs_select
											if ($valDynR['valeur'] && $valDynR['valeur'] != '') {
												$valsMultiListe = explode(",", $valDynR['valeur']);
												$valMultiListe = "";
												foreach ($valsMultiListe as $keyVML => $valML) {
													$valMLSelect = $this->getTableObjet('valeurs_select')->select(array('id' => $valML))->current();
													if ($keyVML == 0) {
														$valMultiListe .= $valMLSelect->valeur;
													} else {
														$valMultiListe .= "|".$valMLSelect->valeur;
													}
												}
												$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, $valMultiListe);
											}
										} else {
											$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col + $keyCD, $keyIdRes + 3, $valDynR['valeur']);
										}
									}
								}
							}
						}
					}
					## champs logement
					if (!empty($champsLoge) && $modeExport == "listes" || $modeExport == "loge_listes") {
						foreach ($champsLoge as $chStand) {
							foreach ($allIdsDossiers as $keyIdR => $idDossier) {
								$idLogement = '';
								if ($modeExport == "listes" || $modeExport == "loge_listes") {
									$dossier = $this->getTableObjet('reservations')->select(array('id' => $idDossier))->current();
									if(!empty($allIdsLoge[$keyIdR])){
										$idLogement = $allIdsLoge[$keyIdR];
									}else{
										$idLogement = $dossier ? $dossier->idLogement : '';
									}
								}
								if(!$idLogement)continue;
								$loge = $this->getLogementTable()->getLogement($idLogement);
								$champName = $chStand->equivalentSql;
								$valStand = property_exists($loge, $champName)? $loge->$champName : '';

								//echo "$champName=$valStand ";
								if ($chStand->idType == 2 && $valStand != '' && substr($valStand,0,2) != '00') {
									$date = new \DateTime($valStand);
									$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $date->format('d/m/Y'));
									$objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $keyIdR + 3)->getNumberFormat()->setFormatCode('dd/mm/yyyy');
								}else{
									if($valStand && $chStand->idType == 3 && $chStand->sourceListe){
										$valSel = $this->getTableObjet($chStand->sourceListe)->select(array('id'=>$valStand))->current();
										$propName = 'nom';
										if($champName=='idTypeBail') $propName = 'typeBail';
										if($champName=='idTypeBien') $propName = 'typeBien';
										if($valSel && property_exists($valSel, $propName)) $valStand = $valSel->$propName;
									}
									$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $keyIdR + 3, $valStand);
								}
							}
							$col++;
						}
					}
					## fin champs logement
				}
			}
		}

		/*foreach(range('B','G') as $columnID) {
			$objPHPExcel->getActiveSheet()->getColumnDimension($columnID)
			->setAutoSize(true);
		}*/
		//echo $objPHPExcel->getActiveSheet()->getHighestDataColumn();exit();
		## auto width les colonnes
		//$sheet = $objPHPExcel->getActiveSheet();
		//$cellIterator = $sheet->getRowIterator()->current()->getCellIterator();
		//$cellIterator->setIterateOnlyExistingCells( true );
		/** @var PHPExcel_Cell $cell */
		//foreach( $cellIterator as $cell ) {
		// $sheet->getColumnDimension( $cell->getColumn() )->setAutoSize( true );
		//}

		// Redirect output to a client’s web browser (Excel5)
		$fileName = $title.'_'.date('d-m-Y-His');

		// Version Excel -> xlsx : Excel2007
		if ($modeExport == "statsListeDP" || $modeExport == "statsListe" || $modeExport == "statsListeDemandes") {
			$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
			$objWriter->setDelimiter(';');  // Define delimiter
		} else {
			$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
		}

		if ($saveFile) {
			if (!is_dir(getcwd()."/public/docs")) {
				mkdir(getcwd()."/public/docs");
			}
			if (!is_dir(getcwd()."/public/docs/pj")) {
				mkdir(getcwd()."/public/docs/pj");
			}
			$dossier = getcwd()."/public/docs/pj/";
			$fullPath = $dossier.$fileName.".xls";
			$session = new Container('mailing');
			$session->listeExportedFile = $fileName.".xls";
			$objWriter->save($fullPath);
			return true;
		} elseif ($modeExport == "statsListeDP" || $modeExport == "statsListe" || $modeExport == "statsListeDemandes" || $extraParams['modeEXT'] == "EXT") {
			if (!is_dir(getcwd()."/public/docs/modeles/statsListes")) {
				mkdir(getcwd()."/public/docs/modeles/statsListes");
			}

			/*if ($modeExport == "statsListeDP") {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
			} elseif ($modeExport == "statsListe") {
				$liste = $this->getTableObjet('listes')->select(array('id' => $idListe))->current();
			} elseif ($modeExport == "statsListeDemandes") {
				$liste = $this->getTableObjet('demandes_listes')->select(array('id' => $idListe))->current();
			}*/

			if ($extraParams['modeEXT'] == "EXT") {
				if ($modeExport == 'statsListeDemandes') {
					$nomFile = $extraParams['nomFichier'];
					$cheminApiStats = $extraParams['cheminApiStats'];
					$cheminDemande = 'Stats Bredea GL/Export/';
					$path = $cheminApiStats.$cheminDemande;
					$objWriter->save($path.$nomFile);
				} else {
					$nomFile = $extraParams['nomCampagne'].".csv";
					$cheminApiStats = $extraParams['cheminApiStats'];
					$cheminStatsCampagne = $extraParams['cheminStatsCampagne'];
					$path = $cheminApiStats.$cheminStatsCampagne;
					$objWriter->save($path.$nomFile);
				}
			} else {
				$path = getcwd()."/public/docs/modeles/statsListes/";
				if (!is_dir(getcwd()."/public/docs/modeles/statsListes/statsZip/")) {
					mkdir(getcwd()."/public/docs/modeles/statsListes/statsZip/");
				}
				$objWriter->save($path."statsZip/exportListe.csv");
			}

			return true;
		} else {
			header('Content-Type: application/vnd.ms-excel');
			header('Content-Disposition: attachment;filename="'.$fileName.'.xls"');
			header('Cache-Control: max-age=0');
			// If you're serving to IE 9, then the following may be needed
			header('Cache-Control: max-age=1');

			// If you're serving to IE over SSL, then the following may be needed
			header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
			header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
			header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
			header('Pragma: public'); // HTTP/1.0
			$objWriter->save('php://output');
		}
		exit();
	}

	//charger les lignes demandées en mode serverSide
	public function getServerJsonDataPresentAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');
			$idListe	= $request->getPost('idListe', 0);
			$isPlanning	= $request->getPost('isPlanning');
			$searchName = $request->getPost('searchName', '');
			$searchPrenom = $request->getPost('searchPrenom', '');
			$searchCodeLocataire = $request->getPost('searchCodeLocataire', '');
			$searchNumeroChambre = $request->getPost('searchNumeroChambre', '');
			$searchArchive = $request->getPost('searchArchive', '');
			$rechercheStricteNom = $request->getPost('rechercheStricteNom', '');
			$rechercheStrictePrenom = $request->getPost('rechercheStrictePrenom', '');
			$rechercheStricteDateNaissance = $request->getPost('rechercheStricteDateNaissance', '');
			$rechercheStricteArchive = $request->getPost('rechercheStricteArchive', '');

			$startDate = $request->getPost('startDate', '');
			$endDate = $request->getPost('endDate', '');

			$startDate = date('Y-m-d', strtotime($startDate));
			$endDate = date('Y-m-d', strtotime($request->getPost('endDate') ? $request->getPost('endDate') : '01-01-2038'));

			## filtre bandeau
			$sessFB = new Container('filtreBandeau');
			$FiltresBandeau = isset($sessFB->filtres) ? $sessFB->filtres : array();

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : draw=$draw start=$start length=$length idListe=$idListe");
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : columns=".json_encode($columns));
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : order=".json_encode($order));


			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe typeListe=$typeListe");

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('draw'	=> 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonResaDatatableState		= $this->loadPresentState();
			$jsonResaDatatableFilter	= $jsonResaDatatableState ? $jsonResaDatatableState['filter'] : [];


			if ($jsonResaDatatableFilter && $columns) {
				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getResaFields(0, $jsonResaDatatableFilter);
				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$listeChampsAffiches	= array(
						'idLocataire' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
						'idReservation' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
						'idGroupeResa' => array('dyn' => 0, 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idGroupeResa', 'visible' => false),

						'dateArrivee' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateArrivee', 'visible' => false),

						'dateArriveeTheorique' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateArriveeTheorique', 'visible' => false),

						'dateDepart' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateDepart', 'visible' => false),

						'dateDepartTheorique' => array('dyn' => 0, 'idTypeHtml' => 2, 'table' => 'reservations', 'equivalentSql' => 'dateDepartTheorique', 'visible' => false),
						);

				foreach ($columns as $_key => $_column) {
					$_colName	= $_column[data];
					if (0) {
						if ($_colName) {
							## Recherche du champ dans les différentes listes de champs
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							foreach ($formFields as $_typeField => $_fields) {
								if (($_field = $_fields[$_colName])) {
									if ($_typeField == 'dynFields') {
										if (array_key_exists($_colName, $listeChampsAffiches)) {
											## Juste un ajout d'un autre champ ID
											## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
											$listeChampsAffiches[$_colName]['idChamp'][]	= $_field->idChamp;
										} else {
											$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
																	'typeField' => $_typeField,
																	'idTypeHtml' => $_field->idTypeHtml,
																	'table' => $_field->table,
																	'idChamp' => array($_field->idChamp),
																	'equivalentSql' => $_field->equivalentSql,
																	'sourceListe' => $_field->sourceListe);
										}
									} else {
										$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
																'typeField' => $_typeField,
																'idTypeHtml' => $_field->idTypeHtml,
																'table' => $_field->table,
																'idChamp' => $_field->id,
																'equivalentSql' => $_field->equivalentSql,
																'sourceListe' => $_field->sourceListe);
									}
									break;
								}
							}
							if (!$listeChampsAffiches[$_colName]) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : _colName=$_colName absent dans fields");
							}
						}
					} else {
						if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
							## Recherche du champ dans les différentes listes de champs
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							foreach ($formFields as $_typeField => $_fields) {
								if ($_typeField == "activeFields") {
									continue;
								}

								if (($_field = $_fields[$_colName])) {
									if ($_typeField == 'dynFields') {
										$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
																'typeField' => $_typeField,
																'idTypeHtml' => $_field->idTypeHtml,
																'table' => $_field->table,
																'idChamp' => $_field->idChamp,
																'equivalentSql' => $_field->equivalentSql,
																'sourceListe' => $_field->sourceListe,
																'visible' => true);
									} else {
										$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
																'typeField' => $_typeField,
																'idTypeHtml' => $_field->idTypeHtml,
																'table' => $_field->table,
																'idChamp' => $_field->id,
																'equivalentSql' => $_field->equivalentSql,
																'sourceListe' => $_field->sourceListe,
																'visible' => true);
									}
									break;
								}
							}
							if (!$listeChampsAffiches[$_colName]) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : _colName=$_colName absent dans fields");
							}
						}
					}
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idListe=$idListe listeChampsAffiches=".json_encode($listeChampsAffiches));

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where	= ($isPlanning && $typeListe == 1) ? array("reservations.etat" => 1) : array();

				$residences = [];
				$gestionnaire_residences = $this->getTableObjet('gestionnaire_residences')->select(array('idGestionnaire' => $gestId));
				foreach ($gestionnaire_residences as $row) {
					$residences[] = $row->idResidence;
				}
				array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".implode(',', $residences)."),1=1 )");

				if ($searchName != "") {
					array_push($where, "locataires.nom LIKE '".$searchName."%'");
				}
				if ($searchPrenom != "") {
					array_push($where, "locataires.prenom LIKE '".$searchPrenom."%'");
				}
				if ($searchCodeLocataire != "") {
					array_push($where, "locataires.codeLocataire LIKE '".$searchCodeLocataire."%'");
				}
				if ($searchNumeroChambre != "") {
					array_push($where, "reservations.numeroChambre LIKE '".$searchNumeroChambre."%'");
				}
				if ($searchArchive == "1") {
					array_push($where, "reservations.archive IN ('0','1')");
				}
				if ($rechercheStricteNom != "") {
					array_push($where, "locataires.nom = '".$rechercheStricteNom."%'");
				}
				if ($rechercheStrictePrenom != "") {
					array_push($where, "locataires.prenom = '".$rechercheStrictePrenom."%'");
				}
				if ($rechercheStricteDateNaissance != "") {
					array_push($where, "locataires.dateNaissance = '".$rechercheStricteDateNaissance."%'");
				}
				if ($rechercheStricteArchive == "1") {
					array_push($where, "reservations.archive IN ('0','1')");
				}

				if ($startDate && $endDate) {
					array_push($where, 'IF(reservations.dateDepart AND reservations.dateDepart!=\'0000-00-00\',reservations.dateDepart > "'.$startDate.'" AND reservations.dateArrivee < "'.$endDate.'", reservations.dateArrivee < "'.$endDate.'")');
				}
				## filtresBandeau
				if (!empty($FiltresBandeau)) {
					if (!empty($FiltresBandeau['idResidence'])) {
						$in = implode(',', $FiltresBandeau['idResidence']);
						array_push($where, "IF(reservations.idLogement > 0,batiments.idResidence IN (".$in."),1=1 )");
					}
					if (!empty($FiltresBandeau['idBatiment'])) {
						$in = implode(',', $FiltresBandeau['idBatiment']);
						array_push($where, "IF(reservations.idLogement > 0,batiments.id IN (".$in."),1=1 )");
					}
					if (!empty($FiltresBandeau['idCampagne'])) {
						$in = implode(',', $FiltresBandeau['idCampagne']);
						array_push($where, "reservations.idCampagne IN ($in)");
					}
					if (!empty($FiltresBandeau['idProgramme'])) {
						$in = implode(',', $FiltresBandeau['idProgramme']);
						array_push($where, "reservations.idProgramme IN ($in)");
					}
					if (!empty($FiltresBandeau['idSousProgramme'])) {
						$in = implode(',', $FiltresBandeau['idSousProgramme']);
						array_push($where, "reservations.idSousProgramme IN ($in)");
					}
				}
				//print_r($where);
				// print_r($listeChampsAffiches);exit();
				$rowsAll = $this->getResaTable()->getListeWithAllFields($adapter, $typeListe, $listeChampsAffiches, $where, array('config' => $conf));
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsAll=".count($rowsAll)." debut_rowsAll=".json_encode(array_slice($rowsAll, 0, 1)));


				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);
				//print_r($rowsAll);exit();
				if ($rowsAll) {
					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					$selectVals = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
								$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					## recup des bonne valeurs des champs de type radio selon la campagne
					$radioOptions = array();
					if (!empty($colRadios)) {
						$tableChampsForms = $this->getTableObjet('champs_formulaires');
						$select = $tableChampsForms->getSql()->select();
						$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
						$select->where->in('equivalentSql', $colRadios);
						$champs = $tableChampsForms->selectWith($select);
						foreach ($champs as $ch) {
							$options = explode(";", $ch->options);
							$radioOptions[$ch->idCampagne][$ch->equivalentSql] = $options;
						}
					}

					if ($colDates || !empty($radioOptions) || !empty($selectVals)) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							if ($colDates) {
								foreach ($colDates as $_colName) {
									$rowValue	= $row[$_colName];
									if ($rowValue && strpos($rowValue, '-') == 2) {
										## Date au format dd-mm-yyyy -> il faut convertir
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $rowValue);
										$row[$_colName]		= "$yyyy-$mm-$dd";
									}
								}
							}
							## remplacer les valeurs radio avec les bonne valeurs
							if (!empty($radioOptions)) {
								foreach ($colRadios as $_colName) {
									if (in_array($_colName, $colRadios)) {
										if (!empty($radioOptions[$row['idCampagne']][$_colName][$row[$_colName]])) {
											$row[$_colName] = $radioOptions[$row['idCampagne']][$_colName][$row[$_colName]];
										} else {
											$row[$_colName] = "";
										}
									}
								}
							}
							##Select multiple
							if(!empty($selectVals)) {
								foreach($selectVals as $_colName => $sVals) {
									$rowValue	= $row[$_colName];
									if($rowValue) {
										$rowValueArr = explode(',', $rowValue);
										if(!empty($rowValueArr)) {
											$rowValueNew = '';
											foreach($rowValueArr as $v) {
												$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
												$rowValueNew .= ', ';
											}
											$rowValueNew = substr($rowValueNew, 0, -2);
											if($rowValueNew) {
												$row[$_colName]	= $rowValueNew;
											}
										}
									}
								}
							}
							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}


					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonResaDatatableFilter as $fieldName => $field) {
						$searchTypes[$fieldName]	= $field['type'];
						if (in_array($fieldName, $colRadios)) {
							$searchTypes[$fieldName]	= "text";
						}//traiter les champs radio comme des text
						if (in_array($fieldName, $colCheckbox)) {
							$searchTypes[$fieldName]	= "checkbox";
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));

					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column[name];
						$value		= $column[search][value];
						//si value == 'null' cad filtre sur valeur vide pour les select
						// si == " " filtre sur valeur vide champs texte
						if ($colName && $column[searchable] && ($value || $value == 'null' || $value == " ")) {
							$searchType	= $searchTypes[$colName];
							if ($value == 'null' || $value == " ") {
								$value = null;
							}
							if ($searchType == 'date' || $searchType == 'number' && $value) {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max)		= explode("|", $value);
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$searchs[$colName][min]		= $min;
								$searchs[$colName][max]		= $max;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$searchs[$colName][text]	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName][colInd]	= $column[data];
								$searchs[$colName][type]	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search[min] && $rowValue < $search[min]) {
										continue 2;
									}
									if ($search[max] && $rowValue > $search[max]) {
										continue 2;
									}
								} elseif ($search['type'] == 'number') {
									if ($search[min] != '' && $rowValue < $search[min]) {
										continue 2;
									}
									if ($search[max] != '' && $rowValue > $search[max]) {
										continue 2;
									}
								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}

					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSel=".count($rowsSel)." debut_rowsSel=".json_encode(array_slice($rowsSel, 0, 1)));
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}

				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : idListe=$idListe count_rowsSlice=".count($rowsSlice)." rows_rowsSlice=".json_encode(array_slice($rowsSlice, 0, 1)));
			}

			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;
			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}

	/**
	 * \brief récupération de la liste des champs sources dans les actions d'une campagne
	 *
	 * \param Integer $idCampagne : Identifiant de la campagne (si 0, on prend tout mais ce n'est pas le but !!!)
	 *
	 * \return Array $idsChampsActions : liste des ids des champs liés aux actions de la campagne
	 */
	private function getChampsLiesAuxActions($idCampagne = 0)
	{
		$sql	= $this->getActionsjsTable()->getSql();
		$select	= $sql->select();
		$select->join(array('champs1' => 'champs_formulaires'), 'champs1.id=actions_js.idChamp', array('champIdFormulaire' => 'idFormulaire', 'champNom' => 'name'), 'LEFT');
		$select->join(array('formulaires1' => 'formulaires'), 'formulaires1.id=champs1.idFormulaire', array('champIdCampagne' => 'idCampagne'), 'LEFT');
		$select->join(array('champs2' => 'champs_formulaires'), 'champs2.id=actions_js.idChampAttache', array('champAttacheIdFormulaire' => 'idFormulaire', 'champAttacheNom' => 'name'), 'LEFT');
		$select->join(array('formulaires2' => 'formulaires'), 'formulaires2.id=champs2.idFormulaire', array('champAttacheIdCampagne' => 'idCampagne'), 'LEFT');

		$select->join('actions_conditions', 'actions_js.id=actions_conditions.idAction', array('idChampCond' => 'idChamp', 'idCond' => 'id'), 'LEFT');

		if ($idCampagne) {
			$select->where("formulaires1.idCampagne = $idCampagne OR formulaires2.idCampagne = $idCampagne");
		}
		## syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idCampagne=$idCampagne sql=".$sql->getSqlstringForSqlObject($select));
		$resultSet	= $this->getActionsJsTable()->selectWith($select);
		$idsChampsActions = array();
		if ($resultSet) {
			foreach ($resultSet as $ra) {
				if (!in_array($ra->idChamp, $idsChampsActions)) {
					$idsChampsActions[] = $ra->idChamp;
				}
				if (!in_array($ra->idChampCond, $idsChampsActions)) {
					$idsChampsActions[] = $ra->idChampCond;
				}
				if (!in_array($ra->idChampAttache, $idsChampsActions)) {
					$idsChampsActions[] = $ra->idChampAttache;
				}
				if ($ra->champDebut > 0 && !in_array($ra->champDebut, $idsChampsActions)) {
					$idsChampsActions[] = $ra->champDebut;
				}
				if ($ra->champFin > 0 && !in_array($ra->champFin, $idsChampsActions)) {
					$idsChampsActions[] = $ra->champFin;
				}
			}
		}
		return $idsChampsActions;
	}


	public function loadActionForward($post)
	{

		$return = $this->forward()->dispatch('Application\Controller\Reservation', array(
											'action' => 'loadActionsForward',
											'params'	=> array('post' => $post),
							));
		if (is_object($return)) {
			$return = $return->getVariables();
		}
		return $return;
	}

	/**
	 * \brief Chargement des actions pour une campagne
	 *
	 * \param Array $post			: Tableau de paramètres avec au moins idCampagne et currentField et éventuellement page et ajax
	 * \param Array $champsFormulaires	: Tableau des champs des formulaires de la campagne avec :
	 *						- 'byId' : la liste des descriptions de champs_formulaires indexée par l'id du champ
	 *						- 'byForm' : la liste des ids de champs_formulaires organisée par idFormulaire
	 *						- 'byName' : la correspondance entre noms de champs et id de champs
	 *
	 * \return Array	: Tableau avec les résultats
	 */
	public function loadActions($post, $champsFormulaire)
	{
		//return $this->loadActionForward($post);//on utlise loadActions() de ReservationController.php la plus à jour

		// echo "<pre>";
		// var_dump($champsFormulaire['byId'][4000]);
		// echo "</pre>";
		// die();

		$session = new Container('formulaire');
		$sessLocataire = new Container('locSess');

		if (!empty($post)) {
			$idCamp = (int) $post['idCampagne'];
			$currentField = $post['currentField'];
			$isAjax = $post['ajax'] ? $post['ajax'] : false;
			$page = !empty($post['page']) ? $post['page'] : "";
			syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currField=$currentField idCamp=$idCamp".($isAjax ? " isAjax=$isAjax " : "").($page ? " page=$page" : ""));

			$typeChampsTable = $this->getTable('type_champs_formulaire');
			$tableComptes = $this->getTable('comptes');

			$typesChamps = array();
			$tcResult = $typeChampsTable->select();
			foreach ($tcResult as $t) {
				$typesChamps[$t->id] = $t;
			}

			unset($post['currentField']);
			unset($post['task']);
			unset($post['idCampagne']);
			unset($post['idProgramme']);

			//aperateurs 1:=, 2 <,3 >, 4 entre
			$operateurs = array('1' => '==', '2' => '<', '3' => '>', '5' => '!=');
			$valide = false;
			$champsNonValide = array();
			$champsDeCriteres = array();//pour la verification au cas de changement de valeur
			$sessDataForm = $post;
			$openPopUp = false;

			$actionResult = array();//on y stock le resultat de chaque condition par action

			$texte = "";

			$idCampagne = $session->idCampagne;
			if (!$idCampagne && $idCamp) {
				$idCampagne = $idCamp;
			}
			$forms = $this->getFormulaireTableModel()->getAllFrontForms($idCamp);
			$idsForm = array();//les ids des formulaire du campagne
			foreach ($forms as $f) {
				$idsForm[] = $f->id;
			}
			if ($page == "recap") {
				$recForms = $this->getFormulaireTableModel()->getFrontFormBy(array('idCampagne' => $idCampagne, 'idType' => 4));
				foreach ($recForms as $f) {
					$idsForm[] = $f->id;
				}
				$recForms = $this->getFormulaireTableModel()->getFrontFormBy(array('idCampagne' => $idCampagne, 'idType' => 5));
				foreach ($recForms as $f) {
					$idsForm[] = $f->id;
				}
			}

			// echo "<pre>";
			// var_dump($idsForm);
			// echo "</pre>";
			// die();


			//$currChamp = $this->getChampsFormTable()->select(array('equivalentSql'=>$currentField))->current();
			//si le champs qui declanche l action est type Logement, on enleve le numero du nom di champ
			$numeroChoix = "";
			$currIdTypeLogement = "";
			if (strpos($currentField, 'idTypeLogement') !== false) {
				$currIdTypeLogement = $currentField;
				$numeroChoix = str_replace('idTypeLogement', '', $currentField);
				$currentField = 'idTypeLogement';
			}
			if ($currentField == 'idTypeLocataire') {
				$currChamp = $this->getTableObjet('champs')->select(array('equivalentSql' => 'idTypeLocataire'))->current();
				if ($currChamp) {
					$currChamp->idType = $currChamp->idTypeHtml;
					$currChamp->id = -2;
				}
			} elseif ($currentField == 'payerDG') {
				$currChamp = $this->getTableObjet('champs')->select(array('equivalentSql' => 'payerDG'))->current();
				if ($currChamp) {
					$currChamp->idType = $currChamp->idTypeHtml;
					$currChamp->id = -3;
				}
			} else {
				$currChamp = $champsFormulaire['byId'][$champsFormulaire['byName'][$currentField]];
			}
			$idChamp	=
			$idFormulaire	= 0;
			if ($currChamp) {
				$idChamp	= $currChamp->id;
				$idFormulaire	= $currChamp->idFormulaire;

				// var_dump($idFormulaire);
				// var_dump($idChamp);
				// die();
			}
			if (!$idChamp || !$idFormulaire) {
				syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currField=$currentField ERROR : impossible d'identifier idChamp ou idFormulaire ????");
			}

			$openPopUp = false;

			$actionsJSTable = $this->getTable("actions_js");
			$actionsConditionsTable = $this->getTable("actions_conditions");

			//on supprime les prefix doc_ pour les type doc pour avoir le bon nom
			$currentField = str_replace('doc_', '', $currentField);

			## Lecture de toutes les actions à partir de ce champ
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$where = array('idChamp' => $idChamp);

			// var_dump($where);die();
			// if ($idChamp == "4000") {
			// 	var_dump("expression");die();
			// }

			//$actions = $actionsJSTable->select($where);

			$sql = $actionsJSTable->getSql();
			$select = $sql->select();


			$select->join('actions_conditions', 'actions_js.id = actions_conditions.idAction', array(
																						'idCond' => 'id',
																						), 'LEFT');
			//$select->where(" (actions_js.idChampAttache = ".$idChamp." OR actions_conditions.idChamp = ".$idChamp." ) ");

			$select->where(" (actions_js.idChamp = ".$idChamp." OR actions_conditions.idChamp = ".$idChamp." OR actions_conditions.champDebut = ".$idChamp." OR actions_conditions.champFin = ".$idChamp." ) ");

			//$actions = $this->getTable("actions_js")->select($where);
			$actions = $actionsJSTable->selectWith($select);

			syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currField=$currentField ($idChamp) idFormulaire=$idFormulaire actions: where=".json_encode($where)." nbActions=".($actions ? $actions->count() : 0));

			if ($actions) {
				foreach ($actions as $action) {
					$condition = true;
					$conditionFinal = true;
					$criteres = $actionsConditionsTable->select(array('idAction' => $action->id));
					syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currField=$currentField ($idChamp) : action=".json_encode($action));
					foreach ($criteres as $c) {
						syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currField=$currentField ($idChamp) : critere=".json_encode($c));
						if ($c->idChamp > 0 || $c->idChamp == -2 || $c->idChamp == -3) {
							if ($c->idChamp == -2) {
								$champ = $this->getTable('champs')->select(array('equivalentSql' => 'idTypeLocataire'))->current();
								if ($champ) {
									$champ->idType = $champ->idTypeHtml;
									## on cherche de quel type de locataire il s agit
									$idTypeLocataire = $sessDataForm['idTypeLocataire'];
									if ($idTypeLocataire > 0) {
										$sessDataForm['idTypeLocataire'] = $idTypeLocataire;
									}
								}
							} elseif ($c->idChamp == -3) {
								$champ = $this->getTable('champs')->select(array('equivalentSql' => 'payerDG'))->current();
								if ($champ && !empty($sessDataForm['idResa'])) {
									$champ->idType = $champ->idTypeHtml;
									## on cherche si il apie ou pas le DG
									$payerDG = $tableComptes->select(array('idReservation' => $sessDataForm['idResa'], 'type' => 4))->current();
									$sessDataForm['payerDG'] = $payerDG ? 1 : 0;
								}
							} else {
								$champ	= $champsFormulaire['byId'][$c->idChamp];
							}
							$champsDeCriteres[$champ->id] = $champ;//pour la verification au cas de changement de valeur
							$type = $typesChamps[$champ->idType];
							$counteur = 1;
							if ($champ->sourceListe == "type_logement") {
								if (!empty($sessDataForm[$champ->equivalentSql.$numeroChoix])) {
									//$champ->equivalentSql = $champ->equivalentSql.$numeroChoix;
									$counteur = $numeroChoix;
								}
							}
							$champEquivalentSql = $champ->equivalentSql;
							for ($p = 1;$p <= $counteur;$p++) {
								if ($p > 1 && $condition) {
									continue;
								}
								if ($champ->sourceListe == "type_logement" && !empty($sessDataForm[$champ->equivalentSql.$p])) {
									$champEquivalentSql = $champ->equivalentSql.$p;
								}

								if ($sessDataForm[$champEquivalentSql] || $sessDataForm[$champEquivalentSql] == 0) {
									$valide = true;
									$valeurLocataire = $sessDataForm[$champEquivalentSql];
									$valeursDb = array();

									if (strpos($c->valeurExact, '[') === false) {
										$valeursDb[] = $c->valeurExact;
									} else {
										$valeursDb = json_decode($c->valeurExact, true);
									}


									foreach ($valeursDb as $valeurDb) {
										syslog(LOG_DEBUG, __FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : currentField=$currentField : equivalentSql=$champEquivalentSql operateur=".$c->operateur." valeurCur=$valeurLocataire valeurCritere=$valeurDb");
										if ($type->nom == 'Date') {
											$valeurDb = strtotime($valeurDb);
											$valeurLocataire = strtotime($valeurLocataire);
										}
										if ($c->operateur == 1) {
											$condition = $valeurLocataire == $valeurDb;
										} elseif ($c->operateur == 2) {
											$condition = $valeurLocataire <= $valeurDb;
										} elseif ($c->operateur == 3) {
											$condition = $valeurLocataire >= $valeurDb;
										} elseif ($c->operateur == 4) {
											$valeurMin = $c->valeurMin;
											$valeurMax = $c->valeurMax;
											if ($type->nom == 'Date') {
												$valeurMin = strtotime($valeurMin);
												$valeurMax = strtotime($valeurMax);
											}
											$condition = $condition && ($valeurMin <= $valeurLocataire) && ($valeurLocataire <= $valeurMax);
										} elseif ($c->operateur == 5) {
											$condition = $valeurLocataire != $valeurDb;
										}
										if ($condition) {
											break;
										}//si on trouve au moins une condition vrai on sort
									}
								} else {
									$champsNonValide[$champ->id] = $champ;
									$condition = false;
								}
							}//end for p
						} else {
							//cas dur?e

							$champDebut = $this->getChampsFormTable()->select(array('id' => $c->champDebut))->current();
							$champFin = $this->getChampsFormTable()->select(array('id' => $c->champFin))->current();

							$champsDeCriteres[$champDebut->id] = $champDebut;
							$champsDeCriteres[$champFin->id] = $champFin;

							$cond = ($champDebut && $champFin)
								|| ($champDebut && $c->champFin == '-1')
								|| ($champFin && $c->champDebut == '-1');


							if ($cond) {
								$valide = true;
								if ($c->champDebut == '-1') {
									$valeurLocataireDebut = date('Y-m-d');
								} else {
									$valeurLocataireDebut = $sessDataForm[$champDebut->equivalentSql];
								}

								if ($c->champFin == '-1') {
									$valeurLocataireFin = date('Y-m-d');
								} else {
									$valeurLocataireFin = $sessDataForm[$champFin->equivalentSql];
								}


								$dateDebut = new \DateTime($valeurLocataireDebut);
								$dateFin = new \DateTime($valeurLocataireFin);
								$difference = $dateDebut->diff($dateFin);

								if ($c->unite == "day") {
									$intervalCalculer = $difference->format('%a');
								} elseif ($c->unite == "week") {
									$intervalCalculer = floor($difference->days / 7);
								} elseif ($c->unite == "year") {
									$intervalCalculer = $difference->format('%y');
								} else {
									//mois
									$intervalCalculer = $difference->format('%m');
								}


								$valeurDb = $c->valeurExact;

								if ($c->operateur == 1) {
									$condition = $intervalCalculer == $valeurDb;
								} elseif ($c->operateur == 2) {
									$condition = $intervalCalculer <= $valeurDb;
								} elseif ($c->operateur == 3) {
									$condition = $intervalCalculer >= $valeurDb;
								} elseif ($c->operateur == 4) {
									$valeurMin = $c->valeurMin;
									$valeurMax = $c->valeurMax;

									$condition = $condition && ($valeurMin <= $intervalCalculer) && ($intervalCalculer <= $valeurMax);
								} elseif ($c->operateur == 5) {
									$condition = $intervalCalculer != $valeurDb;
								}
								/*echo "\n critere ".$c->id;
								var_dump($condition);*/
							} else {
								$champsNonValide[$champDebut->id] = $champDebut;
								$champsNonValide[$champFin->id] = $champFin;
								$condition = false;
							}
						}

						//$champTexte = $this->getChampsFormTable()->select(array('id'=>$c->idChampTexte))->current();
						$texte = $action->texte;
						$conditionFinal = $conditionFinal && $condition;
					}//end foreach criteres

					//$conditionFinal = $conditionFinal && $condition;


					if ($action->idType == 1 || $action->idType == 3 || $action->idType == 6) {
						$champConcerne = $champsFormulaire['byId'][$action->idChampAttache];
						$valeursSelect = array();
						$todo = null;
						if ($action->idType == 1) {
							if ($conditionFinal) {
								$todo = $action->valeur == 1 ? "show" : "hide";
							} else {
								$todo = $action->valeur == 1 ? "hide" : "show";// on fait le contraire si la codition n est pas bonne
							}
						} elseif ($action->idType == 3) {
							//car controle des elements d'une liste
							$todo = "liste";
							if ($action->valeursSelect && $conditionFinal) {
								$valeursSelect = json_decode($action->valeursSelect, true);
							}
						} elseif ($action->idType == 6) {
							if ($conditionFinal) {
								$todo = 'required';
							} else {
								$todo = 'notRequired';
							}
						}
						if ($todo) {
							$actionResult[] = array('condition' => $conditionFinal,
															'action' => $todo,
															'champ' => $champConcerne,
															'valeursSelect' => $valeursSelect,
															'valSelSize' => sizeof($valeursSelect),
															'defaultListeMode' => $action->valeur,
															);
						}
					} elseif ($action->idType == 2 && $conditionFinal) {
						$texte = $action->texte;
						$openPopUp = true;
					}
				}//end foreach
			}



			$return = array(
					'success' => true,
					'valide' => $conditionFinal,
					'texte' => $texte,
					'openPopUp' => $openPopUp,
					'actionResult' => $actionResult,
			);

			return $return;
		}
		return array();
	}

	private function initPMS($idApiPms, $idResa = 0)
	{
		$curIdApiPms	= is_object($this->pms) ? $this->pms->getIdApiPms() : 0;
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiPms=$idApiPms idResa=$idResa curIdApiPms=$curIdApiPms");

		if ($idApiPms && $idApiPms != $curIdApiPms) {

			## Connexion à un nouveau PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~
			try {
				$this->pms	= null;
				$this->pmsGen = null;
				$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$pmsGen		= new PmsGen($adapter, $idApiPms);

				if ($pmsGen) {
					$pms	= $pmsGen->connect(CeriFoyer::TRACE_DEFAULT);
					if (is_object($pms)) {
						$this->pms	= $pms;
						$this->pmsGen = $pmsGen;
					}
				}
				if (!$this->pms) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms injoignable");
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiPms=$idApiPms exception=".$ex->getMessage());
				//echo $ex->getMessage();
			}
		}
	}

	private function initSIG($idApiSig, $idResa = 0)
	{
		$curIdApiSig	= is_object($this->sig) ? $this->sig->getIdApiSig() : 0;
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSig=$idApiSig idResa=$idResa curIdApiSig=$curIdApiSig");

		if ($idApiSig && $idApiSig != $curIdApiSig) {

			## Connexion à un nouveau SIG
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~
			try {
				$this->sig	= null;
				$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$sigGen		= new SigGen($adapter, $idApiSig);
				if ($sigGen) {
					$sig	= $sigGen->connect(CeriFoyer::TRACE_DEFAULT);
					if (is_object($sig)) {
						$this->sig	= $sig;
					}
				}
				if (!$this->sig) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiSig=$idApiSig injoignable");
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa idApiSig=$idApiSig exception=[".$ex->getMessage());
			}
		}
	}

	private function convertAccentedChars($txt)
	{
		$transliterationTable = array('á' => 'a', 'Á' => 'A', 'à' => 'a', 'À' => 'A', 'ă' => 'a', 'Ă' => 'A', 'â' => 'a', 'Â' => 'A', 'å' => 'a', 'Å' => 'A', 'ã' => 'a', 'Ã' => 'A', 'ą' => 'a', 'Ą' => 'A', 'ā' => 'a', 'Ā' => 'A', 'ä' => 'ae', 'Ä' => 'AE', 'æ' => 'ae', 'Æ' => 'AE', 'ḃ' => 'b', 'Ḃ' => 'B', 'ć' => 'c', 'Ć' => 'C', 'ĉ' => 'c', 'Ĉ' => 'C', 'č' => 'c', 'Č' => 'C', 'ċ' => 'c', 'Ċ' => 'C', 'ç' => 'c', 'Ç' => 'C', 'ď' => 'd', 'Ď' => 'D', 'ḋ' => 'd', 'Ḋ' => 'D', 'đ' => 'd', 'Đ' => 'D', 'ð' => 'dh', 'Ð' => 'Dh', 'é' => 'e', 'É' => 'E', 'è' => 'e', 'È' => 'E', 'ĕ' => 'e', 'Ĕ' => 'E', 'ê' => 'e', 'Ê' => 'E', 'ě' => 'e', 'Ě' => 'E', 'ë' => 'e', 'Ë' => 'E', 'ė' => 'e', 'Ė' => 'E', 'ę' => 'e', 'Ę' => 'E', 'ē' => 'e', 'Ē' => 'E', 'ḟ' => 'f', 'Ḟ' => 'F', 'ƒ' => 'f', 'Ƒ' => 'F', 'ğ' => 'g', 'Ğ' => 'G', 'ĝ' => 'g', 'Ĝ' => 'G', 'ġ' => 'g', 'Ġ' => 'G', 'ģ' => 'g', 'Ģ' => 'G', 'ĥ' => 'h', 'Ĥ' => 'H', 'ħ' => 'h', 'Ħ' => 'H', 'í' => 'i', 'Í' => 'I', 'ì' => 'i', 'Ì' => 'I', 'î' => 'i', 'Î' => 'I', 'ï' => 'i', 'Ï' => 'I', 'ĩ' => 'i', 'Ĩ' => 'I', 'į' => 'i', 'Į' => 'I', 'ī' => 'i', 'Ī' => 'I', 'ĵ' => 'j', 'Ĵ' => 'J', 'ķ' => 'k', 'Ķ' => 'K', 'ĺ' => 'l', 'Ĺ' => 'L', 'ľ' => 'l', 'Ľ' => 'L', 'ļ' => 'l', 'Ļ' => 'L', 'ł' => 'l', 'Ł' => 'L', 'ṁ' => 'm', 'Ṁ' => 'M', 'ń' => 'n', 'Ń' => 'N', 'ň' => 'n', 'Ň' => 'N', 'ñ' => 'n', 'Ñ' => 'N', 'ņ' => 'n', 'Ņ' => 'N', 'ó' => 'o', 'Ó' => 'O', 'ò' => 'o', 'Ò' => 'O', 'ô' => 'o', 'Ô' => 'O', 'ő' => 'o', 'Ő' => 'O', 'õ' => 'o', 'Õ' => 'O', 'ø' => 'oe', 'Ø' => 'OE', 'ō' => 'o', 'Ō' => 'O', 'ơ' => 'o', 'Ơ' => 'O', 'ö' => 'oe', 'Ö' => 'OE', 'ṗ' => 'p', 'Ṗ' => 'P', 'ŕ' => 'r', 'Ŕ' => 'R', 'ř' => 'r', 'Ř' => 'R', 'ŗ' => 'r', 'Ŗ' => 'R', 'ś' => 's', 'Ś' => 'S', 'ŝ' => 's', 'Ŝ' => 'S', 'š' => 's', 'Š' => 'S', 'ṡ' => 's', 'Ṡ' => 'S', 'ş' => 's', 'Ş' => 'S', 'ș' => 's', 'Ș' => 'S', 'ß' => 'SS', 'ť' => 't', 'Ť' => 'T', 'ṫ' => 't', 'Ṫ' => 'T', 'ţ' => 't', 'Ţ' => 'T', 'ț' => 't', 'Ț' => 'T', 'ŧ' => 't', 'Ŧ' => 'T', 'ú' => 'u', 'Ú' => 'U', 'ù' => 'u', 'Ù' => 'U', 'ŭ' => 'u', 'Ŭ' => 'U', 'û' => 'u', 'Û' => 'U', 'ů' => 'u', 'Ů' => 'U', 'ű' => 'u', 'Ű' => 'U', 'ũ' => 'u', 'Ũ' => 'U', 'ų' => 'u', 'Ų' => 'U', 'ū' => 'u', 'Ū' => 'U', 'ư' => 'u', 'Ư' => 'U', 'ü' => 'ue', 'Ü' => 'UE', 'ẃ' => 'w', 'Ẃ' => 'W', 'ẁ' => 'w', 'Ẁ' => 'W', 'ŵ' => 'w', 'Ŵ' => 'W', 'ẅ' => 'w', 'Ẅ' => 'W', 'ý' => 'y', 'Ý' => 'Y', 'ỳ' => 'y', 'Ỳ' => 'Y', 'ŷ' => 'y', 'Ŷ' => 'Y', 'ÿ' => 'y', 'Ÿ' => 'Y', 'ź' => 'z', 'Ź' => 'Z', 'ž' => 'z', 'Ž' => 'Z', 'ż' => 'z', 'Ż' => 'Z', 'þ' => 'th', 'Þ' => 'Th', 'µ' => 'u', 'а' => 'a', 'А' => 'a', 'б' => 'b', 'Б' => 'b', 'в' => 'v', 'В' => 'v', 'г' => 'g', 'Г' => 'g', 'д' => 'd', 'Д' => 'd', 'е' => 'e', 'Е' => 'E', 'ё' => 'e', 'Ё' => 'E', 'ж' => 'zh', 'Ж' => 'zh', 'з' => 'z', 'З' => 'z', 'и' => 'i', 'И' => 'i', 'й' => 'j', 'Й' => 'j', 'к' => 'k', 'К' => 'k', 'л' => 'l', 'Л' => 'l', 'м' => 'm', 'М' => 'm', 'н' => 'n', 'Н' => 'n', 'о' => 'o', 'О' => 'o', 'п' => 'p', 'П' => 'p', 'р' => 'r', 'Р' => 'r', 'с' => 's', 'С' => 's', 'т' => 't', 'Т' => 't', 'у' => 'u', 'У' => 'u', 'ф' => 'f', 'Ф' => 'f', 'х' => 'h', 'Х' => 'h', 'ц' => 'c', 'Ц' => 'c', 'ч' => 'ch', 'Ч' => 'ch', 'ш' => 'sh', 'Ш' => 'sh', 'щ' => 'sch', 'Щ' => 'sch', 'ъ' => '', 'Ъ' => '', 'ы' => 'y', 'Ы' => 'y', 'ь' => '', 'Ь' => '', 'э' => 'e', 'Э' => 'e', 'ю' => 'ju', 'Ю' => 'ju', 'я' => 'ja', 'Я' => 'ja');
		return str_replace(array_keys($transliterationTable), array_values($transliterationTable), $txt);
	}

	public function creationODCompte($idResa)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);

		if (!$idResa) {
			return false;
		}
		$resa = $this->getResaTable()->getResa($idResa);
		if (!$resa) {
			return false;
		}
		if (!$resa->numDossier) {
			return false;
		}

		if ($conf && $conf->bredea == 1) {
			try {
				$modePaiementCampagne = $this->getModePaiementCampagne($resa->idCampagne);
				//$bredea = new BredeaSql();
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea', $resa->idApiPms ? $resa->idApiPms : 0);
				## on cree la facture des autre prestation
				$comptes = $this->getTableObjet('comptes')->select(array('idReservation' => $idResa));
				$prestations = array();
				$montantPrestations = array();
				$montant = 0;
				foreach ($comptes as $c) {
					if ($c->type == 4) {
						continue;
					}
					//on fait l OD que pour les lignes paye
					if ($c->etat == 1) {
						$typePresation = $this->getTableObjet('type_prestation')->select(array('id' => $c->type))->current();

						if ($c->type == 3 &&  ($conf->encaisAcompte == 1 && $conf->prestationFDD || $modePaiementCampagne == 'paiementDirect')) {
							## on recup le montant d'acompte 001facompte : acomp_site, acomp_dossier, acomp_mteuro
							$aCompte = $bredea->getRow('001facompte', array('acomp_site' => $resa->codeSite, 'acomp_dossier' => $resa->numResa));
							if (!empty($aCompte) && !empty($aCompte['acomp_mteuro'])) {
								$c->debit	= $aCompte['acomp_mteuro'];
							}

							//cas paiement des frais via acompte
							$montant += $c->debit;
							if ($conf->encaisAcompte == 1 && $conf->prestationFDD) {
								$prestations[$conf->prestationFDD] = '1';
								$montantPrestations[$conf->prestationFDD] = $c->debit;
							} else {
								$prestations[$typePresation->prestationFDD] = '1';
								$montantPrestations[$typePresation->prestationFDD] = $c->debit;
							}
						} else {
							$montant += $c->solde;
							$prestations[$typePresation->codePrestation] = '1';
							$montantPrestations[$typePresation->codePrestation] = $c->debit;
						}
					}
				}
				$dataFact = array();
				$dataFact['codeSite'] 	= $resa->codeSite;
				$dataFact['numDossier']	= $resa->numDossier;
				$dataFact['numResa']	= $resa->numResa;
				$dataFact['typre']		= $resa->typre ? $resa->typre : 'R';
				$dataFact['montant']	= $montant;

				$ret	= $bredea->creationODcompte($dataFact);
				$bredea->closeConnect();
				return $ret;
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
	}

	## verification si on a deja un OD compte de creer
	public function checkODCompte($idResa)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);

		if (!$idResa) {
			return false;
		}
		$resa = $this->getResaTable()->getResa($idResa);
		if (!$resa) {
			return false;
		}
		if (!$resa->numDossier) {
			return false;
		}

		if ($conf && $conf->bredea == 1) {
			try {
				//$bredea = new BredeaSql();
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea', $resa->idApiPms ? $resa->idApiPms : 0);

				$where = array();
				$where['hfa_site'] 	= $resa->codeSite;
				$where['hfa_dossier']	= $resa->numDossier;
				$where['hfa_typre']		= $resa->typre ? $resa->typre : 'R';
				$where['hfa_modreg']	= 'OD';

				$rows	= $bredea->getRows('001fhistofac', $where);
				if (empty($rows)) {
					return false;
				} else {
					return true;
				}
				$bredea->closeConnect();
				return $ret;
			} catch (\Exception $ex) {
				echo $ex->getMessage();
			}
		}
		return false;
	}

	public function testODCautionAction()
	{
		$idResa = (isset($_GET['idResa']) && $_GET['idResa'] != "") ? $_GET['idResa'] : null;
		if($idResa) {
			$ODCreer = $this->checkODCompte($idResa);
			var_dump($ODCreer);
			//$this->creationODAcompteCaution($idResa);
		}
		exit();
	}

	public function creationODAcompteCaution($idResa)
	{
		$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
		if ($bredea) {
			try {
				$tableResa = $this->getTableObjet('reservations');
				$tableComptes = $this->getTableObjet('comptes');

				$resa = $tableResa->select(array('id' => $idResa))->current();

				$comptes = $tableComptes->select(array('idReservation' => $idResa));
				foreach ($comptes as $c) {
					if ($c->type == 4 && $c->etat == 1) {

						//$regData['montantCaution'] = $c->solde;
						//on cree la ligne caution
						$cDataCaution = array();
						$cDataCaution['numDossier'] = $resa->numDossier;
						$cDataCaution['typre'] = $resa->typre ? $resa->typre : 'R';
						$cDataCaution['codeSite'] = $resa->codeSite;
						$cDataCaution['montantCaution'] = $c->debit;
						$cDataCaution['date'] = date('Ymd');
						$cDataCaution['modeReglement'] = 'OD';
						## on recup le montant d'acompte 001facompte : acomp_site, acomp_dossier, acomp_mteuro
						$aCompte = $bredea->getRow('001facompte', array('acomp_site' => $resa->codeSite, 'acomp_dossier' => $resa->numResa));
						if (!empty($aCompte) && !empty($aCompte['acomp_mtcaution'])) {
							$cDataCaution['montantCaution']	= $aCompte['acomp_mtcaution'];
						}

						$noPieceCaution = $bredea->creationODAcompteCaution($cDataCaution);

						$log = new Logs();
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = 0;
						$log->operation = "CheckIN creation caution de résa $idResa";
						$log->dataBefore = array();
						$log->dataAfter = $cDataCaution;
						$log->tableName = "Bredea";
						$log->idLocataire = $resa->idLocataire;
						$log->idReservation = $resa->id;
						$this->getLogsTable()->saveLogs($log);
					}
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
			$bredea->closeConnect();
		}
	}

	public function getGlobalHelper()
	{
		if (!$this->globalHelper) {
			$this->globalHelper = new GlobalHelper($this->getServiceLocator());
		}
		return $this->globalHelper;
	}

	public function getHistoriqueMailUsersTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->HistoriqueMailUsersTable) {
			$this->HistoriqueMailUsersTable = new HistoriqueMailUsersTable($adapter);
		}
		return $this->HistoriqueMailUsersTable;
	}

	## script re-envois de mail
	public function reSendMailAction()
	{
		$idModele = 155;
		$tableResa = $this->getTableObjet('reservations');
		$tableLoc = $this->getTableObjet('locataires');

		$table = $this->getTableObjet('historique_mail');
		$select = $table->getSql()->select();
		$select->where("dateEnvoi > '2019-09-10' AND idModele=$idModele ");
		$rows = $table->selectWith($select);
		$i = 0;
		foreach ($rows as $row) {
			$idLoc = $row->idLocataire;
			$selectResa = $tableResa->getSql()->select();
			$selectResa->where(array('idLocataire' => $idLoc, 'archive' => '0', 'etat' => 7));
			$resa = $table->selectWith($selectResa)->current();
			if ($resa) {
				$loc = $tableLoc->select(array('id' => $idLoc))->current();
				## fonction d'envois de mail :
				///$this->envoyerMail($resa->id,0,$idModele);
				$i++;
				echo "Mail envoye a $loc->email <br>";
			}
		}
		echo "$i mail envoye";
		exit();
	}

	## FICHE Historique->paroucrs : load DP et RESAS DE LOC
	public function loadParcoursTab($idLocataire, $idLigneCourant = null, $isResa = null)
	{
		if (!$idLocataire) {
			return 'Aucun locataire fournis';
		}

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$translator->setLocale('fr_FR');

		## on recup les résa de ce locataire
		$resaRows = $this->getResaTable()->getLocParcours($idLocataire);

		foreach ($resaRows as $row) {
			$configParcoursRow = $this->getConfigParcoursTable()->getConfigParCampagne(array($row->idCampagne));

			if (!empty($configParcoursRow[$row->idCampagne]['dateEntree'])) {
				$idChampDateEntree = $configParcoursRow[$row->idCampagne]['dateEntree'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateEntree, 'idReservation' => $row->id));
				if ($val) {
					$row->dateArrivee = $val->valeur;
				}
			}
			if (!empty($configParcoursRow[$row->idCampagne]['dateSortie'])) {
				$idChampDateSortie = $configParcoursRow[$row->idCampagne]['dateSortie'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateSortie, 'idReservation' => $row->id));
				if ($val) {
					$row->dateDepart = $val->valeur;
				}
			}
		}

		## on récup les DP de ce locataire
		$dpRows = $this->getDomiciliationsTable()->getLocParcours($idLocataire, 'tabLogs');

		foreach ($dpRows as $row) {
			$configParcoursRow = $this->getConfigParcoursTable()->getConfigParCampagne(array($row->idCampagne));

			if (!empty($configParcoursRow[$row->idCampagne]['dateEntree'])) {
				$idChampDateEntree = $configParcoursRow[$row->idCampagne]['dateEntree'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateEntree, 'idDp' => $row->id));
				if ($val) {
					$row->dateEntree = $val->valeur;
				}
			}
			if (!empty($configParcoursRow[$row->idCampagne]['dateSortie'])) {
				$idChampDateSortie = $configParcoursRow[$row->idCampagne]['dateSortie'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateSortie, 'idDp' => $row->id));
				if ($val) {
					$row->dateSortie = $val->valeur;
				}
			}
		}
		$currentDps = $this->getDomiciliationsTable()->getCurrentDps($idLocataire);
		$currentIds = array();
		foreach ($currentDps as $d) {
			$currentIds[] = $d->id;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/parcourstab')
		->setVariables(array(
				"resaRows" => $resaRows,
				"dpRows" => $dpRows,
				"idLocataire" => $idLocataire,
				//"idLigneCourant" => $currentDp ? $currentDp->id : $idLigneCourant,
				"idLigneCourant" => !empty($currentIds) ? $currentIds : $idLigneCourant,
				"isResa" => $isResa,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	## FICHE Historique séjours
	public function loadHistoriqueSejoursTab($idLocataire, $idResa = null)
	{
		if (!$idLocataire) {
			return 'Aucun locataire fournis';
		}

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();
		$translator->setLocale('fr_FR');
		$config = $this->getConfigurationTable()->getConfig(1);

		## on recup les résa de ce locataire
		$resaRows = $this->getResaTable()->getLocParcours($idLocataire, $chefFamilleParcours = true);

		foreach ($resaRows as $row) {
			$configParcoursRow = $this->getConfigParcoursTable()->getConfigParCampagne(array($row->idCampagne));

			if (!empty($configParcoursRow[$row->idCampagne]['dateEntree'])) {
				$idChampDateEntree = $configParcoursRow[$row->idCampagne]['dateEntree'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateEntree, 'idReservation' => $row->id));
				if ($val) {
					$row->dateArrivee = $val->valeur;
				}
			}
			if (!empty($configParcoursRow[$row->idCampagne]['dateSortie'])) {
				$idChampDateSortie = $configParcoursRow[$row->idCampagne]['dateSortie'];
				$val = $this->getConfigParcoursTable()->getValeurChampBy(array('idChamp' => $idChampDateSortie, 'idReservation' => $row->id));
				if ($val) {
					$row->dateDepart = $val->valeur;
				}
			}
		}

		$residences =  $this->getResidencesTable()->fetchByGest($gestId);

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/historiquesejourstab')
		->setVariables(array(
				"resaRows" => $resaRows,
				"idLocataire" => $idLocataire,
				"idResa" => $idResa,
				"now"	=> date('Y-m-d'),
				"conf" => $config,
				"residences" => $residences,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}


	public function getDomiciliationsTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->domiciliationsTable) {
			$this->domiciliationsTable = new DomiciliationsTable($adapter);
		}
		return $this->domiciliationsTable;
	}

	public function getDroitTable()
	{
		if (!$this->droitTable) {
			$sm = $this->getServiceLocator();
			$this->droitTable = $sm->get('Reservation\Model\DroitTable');
		}
		return $this->droitTable;
	}

	public function getConfigParcoursTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->configParcousTable) {
			$this->configParcousTable = new ConfigParcousTable($adapter);
		}
		return $this->configParcousTable;
	}

	public function getApipmsTable()
	{
		$sm = $this->getServiceLocator();
		return $sm->get('Reservation\Model\ApipmsTable');
	}

	public function getApisigTable()
	{
		$sm = $this->getServiceLocator();
		return $sm->get('Reservation\Model\ApisigTable');
	}

	private function checkMajStatutRIB($idReservation, $idChamp, $nouvelleValeur)
	{

		## on verifie si la valeur de l'un des champ rib est changé ou  ajouté, si oui change le statutRIB en modifier
		$tableValDyn = $this->getTableObjet('valeurs_dynamiques');
		$tableResa =  $this->getTableObjet('reservations');
		$oldVal = $tableValDyn->select(array('idChamp' => $idChamp, 'idReservation' => $idReservation))->current();
		$modifier = false;
		if ($oldVal) {
			if ($oldVal->valeur != $nouvelleValeur) {
				$modifier = true;
			}
		} elseif ($nouvelleValeur) {
			$modifier = true;
		}

		if ($modifier) {
			$tableResa->update(array('statutRIB' => 'modifier'), array('id' => $idReservation));
		}
	}

	private function copierValeurChampCommun($champ, $post)
	{
		if($champ && $champ->idChampCommun > 0) {
			$tools = new Tools();
			$tableValDyn = $this->getTableObjet('valeurs_dynamiques');
			$tableCF = $this->getTableObjet('champs_formulaires');
			$tableCB = $this->getTableObjet('champs_de_base');
			$tableTypeChamp = $this->getTableObjet('type_champs_formulaire');

			$typeChampRes = $tableTypeChamp->select(array('id' => $champ->idType))->current();

			$champName = $champ->equivalentSql;
			$typeChamp = $typeChampRes ? $typeChampRes->type : '';
			if ($typeChamp == "File") {
				$champName = "doc_".$champName;
			}

			$valeur = $post[$champName];
			if ($champ->idParent) {
				//on recup le champ parent
				$champParent = $tableCF->select(array('id' => $champ->idParent))->current();
				if (!$champParent) {
					continue;
				}

				// on set la valeur à partir du champ parent
				if (isset($post[$champParent->equivalentSql])) {
					$valeur = $post[$champParent->equivalentSql];
				}
			}

			if ($champ->idType == 18) {
				if(is_array($valeur)) {
					if (is_array($valeur[0]) && $valeur[0][0] != "") {
						$valeur = $valeur[0][0];
					} else {
						$valeur = !empty($valeur[0]) ? implode(',', $valeur) : '';
					}
				}
			}

			$idChampCommun = $champ->idChampCommun;

			$champCommun = $tableCF->select(array('id' => $idChampCommun))->current();
			if(!$champCommun || !$valeur) {
				return false;
			}
			$idResa = $idDp = null;
			if (isset($post['idResa']) && $post['idResa'] > 0) {
				$idResa = $post['idResa'];
			}
			if (isset($post['idDp']) && $post['idDp'] > 0) {
				$idDp = $post['idDp'];
			}
			$idLocataire = $post['idLocataire'];


			if($champCommun->nature == 'libre') {
				$valeursObj = new Valeurschampdynamique();
				$valeursObj->idChamp = $champ->id;
				$valeursObj->valeur = $valeur;
				$valeursObj->typeChamp = $typeChamp;
				$valeursObj->idLocataire = $idLocataire;
				if ($idResa > 0) {
					$valeursObj->idReservation = $idResa;
				}
				if ($idDp > 0) {
					$valeursObj->idDp = $idDp;
				}
				if($valeur && ($valeursObj->idReservation || $valeursObj->idDp)) {

					if($champ->nature == 'libre') {
						//tested
						$where = array();
						$where['idChamp'] = $valeursObj->idChamp;
						if($valeursObj->idReservation) {
							$where['idReservation'] = $valeursObj->idReservation;
						}
						if($valeursObj->idDp) {
							$where['idDp'] = $valeursObj->idDp;
						}
						if(!empty($where)) {
							$oldVal = $tableValDyn->select($where)->current();
							if($champCommun->idType == 2 && $oldVal && $oldVal->valeur) {
								$oldVal->valeur = date('Y-m-d', strtotime($oldVal->valeur));
								$valeur = date('Y-m-d', strtotime($valeur));
							}
							if($oldVal && trim($oldVal->valeur) == trim($valeur)) {
								$where['idChamp'] = $idChampCommun;
								$valeursObj->idChamp = $idChampCommun;
								$val = $tableValDyn->select($where)->current();
								if(!$val) {
									$this->getValeurschampdynamiqueTable()->save($valeursObj);
								} elseif(!$val->valeur) {
									$tableValDyn->update(array('valeur' => $valeur), $where);
								}
							}
						}
					} elseif($champ->nature == 'standard') {
						//testted
						$champBase = $tableCB->select(array('equivalentSql' => $champ->equivalentSql))->current();
						if($champBase) {
							if($champBase->tableSql == 'locataires' || $champBase->tableSql == 'reservations' || $champBase->tableSql == 'domiciliations') {
								$whereBase = array();
								if($champBase->tableSql == 'locataires' && $idLocataire) {
									$whereBase['id'] = $idLocataire;
								}
								if($champBase->tableSql == 'reservations' && $idResa) {
									$whereBase['id'] = $idResa;
								}
								if($champBase->tableSql == 'domiciliations' && $idDp) {
									$whereBase['id'] = $idDp;
								}

								$oldVal = $this->getTableObjet($champBase->tableSql)->select($whereBase)->current();
								$champBaseName = $champ->equivalentSql;
								if($oldVal && (trim($oldVal->$champBaseName) == trim($valeur) || ($champ->idType == 2 && date('Y-m-d', strtotime($valeur)) == date('Y-m-d', strtotime($oldVal->$champBaseName))))) {
									$where = array();
									if($valeursObj->idReservation) {
										$where['idReservation'] = $valeursObj->idReservation;
									}
									if($valeursObj->idDp) {
										$where['idDp'] = $valeursObj->idDp;
									}
									if(!empty($where)) {
										$where['idChamp'] = $idChampCommun;
										$valeursObj->idChamp = $idChampCommun;
										$val = $tableValDyn->select($where)->current();
										if(!$val) {
											$this->getValeurschampdynamiqueTable()->save($valeursObj);
										} elseif(!$val->valeur) {
											$tableValDyn->update(array('valeur' => $valeur), $where);
										}
									}
								}//if($oldVal &&
							}
						}//if($champBase){
					}//}elseif($champ->nature == 'standard'){
				}
			} elseif($champCommun->nature == 'standard') {
				if($champ->nature == 'standard') {
					//testing
					$champBaseCom = $tableCB->select(array('equivalentSql' => $champCommun->equivalentSql))->current();
					$champBase = $tableCB->select(array('equivalentSql' => $champ->equivalentSql))->current();
					if($champBase && $champBaseCom) {
						if($champBase->tableSql == 'locataires' || $champBase->tableSql == 'reservations' || $champBase->tableSql == 'domiciliations' || $champBaseCom->tableSql == 'locataires' || $champBaseCom->tableSql == 'reservations' || $champBaseCom->tableSql == 'domiciliations') {
							$whereBase = array();
							if($champBase->tableSql == 'locataires' && $idLocataire) {
								$whereBase['id'] = $idLocataire;
							}
							if($champBase->tableSql == 'reservations' && $idResa) {
								$whereBase['id'] = $idResa;
							}
							if($champBase->tableSql == 'domiciliations' && $idDp) {
								$whereBase['id'] = $idDp;
							}

							$whereBaseCom = array();
							if($champBaseCom->tableSql == 'locataires' && $idLocataire) {
								$whereBaseCom['id'] = $idLocataire;
							}
							if($champBaseCom->tableSql == 'reservations' && $idResa) {
								$whereBaseCom['id'] = $idResa;
							}
							if($champBaseCom->tableSql == 'domiciliations' && $idDp) {
								$whereBaseCom['id'] = $idDp;
							}

							if(!empty($whereBase) && !empty($whereBaseCom)) {
								$oldVal = $this->getTableObjet($champBase->tableSql)->select($whereBase)->current();
								$champBaseName = $champ->equivalentSql;
								if($oldVal && (trim($oldVal->$champBaseName) == trim($valeur) || ($champ->idType == 2 && date('Y-m-d', strtotime($valeur)) == date('Y-m-d', strtotime($oldVal->$champBaseName))))) {

									$oldVal = $this->getTableObjet($champBaseCom->tableSql)->select($whereBaseCom)->current();
									$champBaseNameCom = $champCommun->equivalentSql;
									if($oldVal && (!trim($oldVal->$champBaseNameCom) || ($champCommun->idType == 2 && substr($oldVal->$champBaseNameCom, 0, 2) == '00'))) {
										if($champ->idType == 2) {
											$valeur = date('Y-m-d', strtotime($valeur));
										}
										$this->getTableObjet($champBaseCom->tableSql)->update(array("$champBaseNameCom" => $valeur), $whereBaseCom);
									}
								}
							}
						}
					}//if($champBase && $champBaseCom){

				} elseif($champ->nature == 'libre') {
					//tested
					$champBase = $tableCB->select(array('equivalentSql' => $champCommun->equivalentSql))->current();
					if($champBase) {
						if($champBase->tableSql == 'locataires' || $champBase->tableSql == 'reservations' || $champBase->tableSql == 'domiciliations') {
							$whereBase = array();
							if($champBase->tableSql == 'locataires' && $idLocataire) {
								$whereBase['id'] = $idLocataire;
							}
							if($champBase->tableSql == 'reservations' && $idResa) {
								$whereBase['id'] = $idResa;
							}
							if($champBase->tableSql == 'domiciliations' && $idDp) {
								$whereBase['id'] = $idDp;
							}
							$where = array();
							$where['idChamp'] = $champ->id;
							if($idResa) {
								$where['idReservation'] = $idResa;
							}
							if($idDp) {
								$where['idDp'] = $idDp;
							}
							if(!empty($where)) {
								$oldVal = $tableValDyn->select($where)->current();
								if($champCommun->idType == 2 && $oldVal && $oldVal->valeur) {
									$oldVal->valeur = date('Y-m-d', strtotime($oldVal->valeur));
									$valeur = date('Y-m-d', strtotime($valeur));
								}
								if($oldVal && trim($oldVal->valeur) == trim($valeur)) {
									$oldVal = $this->getTableObjet($champBase->tableSql)->select($whereBase)->current();
									$champBaseName = $champCommun->equivalentSql;
									if($oldVal && (!trim($oldVal->$champBaseName) || ($champCommun->idType == 2 && substr($oldVal->$champBaseName, 0, 2) == '00'))) {
										if($champ->idType == 2) {
											$valeur = date('Y-m-d', strtotime($valeur));
										}
										$this->getTableObjet($champBase->tableSql)->update(array("$champBaseName" => $valeur), $whereBase);
									}
								}
							}
						}
					}//if($champBase){
				}
			}//if($champCommun->nature == 'libre'){
		}
	}

	private function isRIBRempli($idResa, $typeRetour = 'msg')
	{
		$tableVD = $this->getTableObjet('valeurs_dynamiques');
		$select = $tableVD->getSql()->select();
		$select->join('champs_formulaires', 'valeurs_dynamiques.idChamp = champs_formulaires.id', array('idChamp' => 'id', 'idType', 'nomXML'));
		$select->where(array('valeurs_dynamiques.idReservation' => $idResa));
		$select->where("(champs_formulaires.idType IN(15,16) OR champs_formulaires.nomXML = 'rib_nomrib')");
		$rows = $tableVD->selectWith($select);
		$rib = null;
		$bic = null;
		$nomRIB = null;
		foreach ($rows as $row) {
			if ($row->valeur) {
				if ($row->idType == 15) {
					$rib = $row->valeur;
				} elseif ($row->idType == 16) {
					$bic = $row->valeur;
				} elseif ($row->nomXML == 'rib_nomrib') {
					$nomRIB = $row->valeur;
				}
			}
		}

		if($typeRetour == 'tableau') {
			$ret = array();
			if ($rib && $bic && $nomRIB) {
				$ret['rib'] = $rib;
				$ret['bic'] = $bic;
				$ret['nomRIB'] = $nomRIB;
			}
		} else {
			$ret = '';
			if ($rib && $bic && $nomRIB) {
				$ret = 'ok';
			} else {
				$ret .= !$rib ? "Champ RIB vide<br>" : '';
				$ret .= !$bic ? "Champ BIC vide<br>" : '';
				$ret .= !$nomRIB ? "Champ nom RIB vide<br>" : '';
			}
		}
		return $ret;
	}


	##archiva DP
	public function archiverdpAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idsDp = $request->getPost('ids', array());
			$dpRows = $this->getDomiciliationsTable()->getDpRowsByIds($idsDp);

			$dpNeedFielsArchive = [];

			foreach ($dpRows as $dp) {
				$allFielObligatoireArchiveOk = true;

				// pour chaque reservation on regarde si on a des champs obligatoire non rempli
				$formulaires = $this->getTableObjet('formulaires')
				->select(array('idCampagne' => $dp->idCampagne))->toArray();

				if (count($formulaires) > 0) {
					foreach ($formulaires as $key => $f) {
						$champs_formulaires = $this->getTableObjet('champs_formulaires')
						->select(array('idFormulaire' => $f['id'], 'obligatoireArchivage' => '1'))
						->toArray();

						if (count($champs_formulaires) > 0) {
							$champsArchiveNotOk = [];
							foreach ($champs_formulaires as $key => $cf) {
								// on vérifie si on a une valeur
								$vd = $this->getTableObjet('valeurs_dynamiques')
								->select(array('idChamp' => $cf['id'], 'idDp' => $dp->id))
								->current();
								if (!$vd || $vd->valeur == '') {
									$champsArchiveNotOk[] = $cf;
								}
							}

							// tous les champs obligatoires pour l'archivage sont vides
							if (count($champsArchiveNotOk) > 0) {
								$dp->champsVides = $champsArchiveNotOk;
								$allFielObligatoireArchiveOk = false;
							}
						}
					}
				}

				if (!$allFielObligatoireArchiveOk) {
					$loc = $this->getTableObjet('locataires')
					->select(array('id' => $dp->idLocataire))->current();

					if ($loc) {
						$dp->nomLocataire = $loc->nom;
						$dp->prenomLocataire = $loc->prenom;

						array_push($dpNeedFielsArchive, $dp);
						continue;
					}
				}

				$this->getDomiciliationsTable()->archiver($dp->id);

				### save logs
				$log = new Logs();
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO Archivage domiciliation ".$dp->id;
				$log->dataBefore = array('archive' => '0');
				$log->dataAfter = array('archive' => '1');
				$log->tableName = "domiciliations";
				$log->idReservation = null;
				$log->idLocataire = $dp->idLocataire;
				$this->getLogsTable()->saveLogs($log);
			}

			$view = new JsonModel(array(
				'success' => true,
				'dpNeedFielsArchive' => $dpNeedFielsArchive,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	##Suppression définitf de DP
	public function deletedpAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$msg = '';
		$tableVD = $this->getTableObjet('valeurs_dynamiques');
		$tableSuivis = $this->getTableObjet('suivis');
		$tableSuivisVD = $this->getTableObjet('suivis_values');
		$tableDocs = $this->getTableObjet('documents');
		$tableDocsResa = $this->getTableObjet('document_locataire');

		if ($request->isXmlHttpRequest()) {
			$idsDp = $request->getPost('ids', array());
			$dpRows = $this->getDomiciliationsTable()->getDpRowsByIds($idsDp);
			foreach ($dpRows as $dp) {
				$this->getDomiciliationsTable()->deleteDp($dp->id);

				### save logs
				$log = new Logs();
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO suppression domiciliation ID ".$dp->id;
				$log->dataBefore = $dp;
				$log->dataAfter = array();
				$log->tableName = "domiciliations";
				$log->idReservation = null;
				$log->idLocataire = $dp->idLocataire;
				$this->getLogsTable()->saveLogs($log);

				## on supprime des valeurs dynamiques
				$result = $tableVD->select(array('idDp' => $dp->id));
				if ($result->count() > 0) {
					$vals = $result->toArray();
					$tableVD->delete(array('idDp' => $dp->id));
					### save logs
					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO suppression de valeurs dynamiques pour la domiciliation ID ".$dp->id;
					$log->dataBefore = $vals;
					$log->dataAfter = array();
					$log->tableName = "valeurs_dynamiques";
					$log->idReservation = null;
					$log->idLocataire = $dp->idLocataire;
					$this->getLogsTable()->saveLogs($log);
				}

				## suppression des ms
				$msRows = $tableSuivis->select(array('idDp' => $dp->id));
				if($msRows->count() > 0) {
					$vals = $msRows->toArray();
					$tableSuivis->delete(array('idDp' => $dp->id));
					### save logs
					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO suppression de suivis pour la domiciliation ".$dp->id;
					$log->dataBefore = $vals;
					$log->dataAfter = array();
					$log->tableName = "suivis";
					$log->idReservation = null;
					$log->idLocataire = $dp->idLocataire;
					$this->getLogsTable()->saveLogs($log);
				}
				$msRows = $tableSuivisVD->select(array('idDp' => $dp->id));
				if($msRows->count() > 0) {
					$vals = $msRows->toArray();
					$tableSuivisVD->delete(array('idDp' => $dp->id));
					### save logs
					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO suppression de valeurs dynamiques suivis pour la domiciliation ".$dp->id;
					$log->dataBefore = $vals;
					$log->dataAfter = array();
					$log->tableName = "suivis_values";
					$log->idReservation = null;
					$log->idLocataire = $dp->idLocataire;
					$this->getLogsTable()->saveLogs($log);
				}
				$msg = 'Suppresion bien faite';
			}

			$view = new JsonModel(array(
				'success' => true,
				'msg' => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	## script de creation de droit de suppresion/modification/affichage pour les modes de listes en lecture/ecriture
	public function creerBoutonsDroitsDeModesDeListesAction()
	{
		$tableDroitElements = $this->getTableObjet('droit_elements');
		$tableDroitConfig = $this->getTableObjet('droit_config');
		$typesSuivis = $this->getListeTypesSuivis();
		$modes = array('liste-input-mode-liste', 'mode-input-dp', 'mode-input-facture', 'mode-input-prestation', 'mode-input-logements');
		foreach ($typesSuivis as $id => $type) {
			$modes[] = 'mode-input-typesuivis-'.$id;
		}

		$i = 0;
		foreach ($modes as $mode) {
			if ($mode == 'liste-input-mode-liste' || $mode == 'mode-input-dp' || $mode == 'mode-input-facture' || $mode == 'mode-input-prestation') {
				$btnDelete = $mode.'-btn-delete';
				$btnSave = $mode.'-btn-save';
				$btnChamp = $mode.'-btn-champs';
			} elseif ($mode == 'mode-input-logements') {
				$btnDelete = 'mode-input-loge-btn-delete';
				$btnSave = 'mode-input-loge-btn-save';
				$btnChamp = 'mode-input-loge-btn-champs';
			} else {
				//type suivis
				$btnDelete = 'mode-input-typesuivis-btn-delete';
				$btnSave = 'mode-input-typesuivis-btn-save';
				$btnChamp = 'mode-input-typesuivis-btn-champs';
			}

			// on cherche le mode
			$modeDroit = $tableDroitElements->select(array('unique_name' => $mode))->current();

			// on cherche les boutons
			$btnDeleteDroit = $tableDroitElements->select(array('unique_name' => $btnDelete))->current();
			$btnSaveDroit = $tableDroitElements->select(array('unique_name' => $btnSave))->current();
			$btnChampDroit = $tableDroitElements->select(array('unique_name' => $btnChamp))->current();

			if ($modeDroit) {
				//on cherche les profis avec le mode en W
				//$droits = $tableDroitConfig->select(array('droit_id'=>$modeDroit->id,'value'=>'W'));
				$select = $tableDroitConfig->getSql()->select();
				$select->join('user_role', 'user_role.role_id = droit_config.role_id', array('role_id'));
				$select->where(
					array('droit_config.droit_id' => $modeDroit->id,
									'droit_config.value' => 'W',
									'user_role.is_default' => 0,
									)
				);
				$droits = $tableDroitConfig->selectWith($select);
				foreach ($droits as $d) {
					//on verifie si on a pas deja le droit pour chaque bouton bouton
					if ($btnDeleteDroit) {
						$droitExist = $tableDroitConfig->select(array('droit_id' => $btnDeleteDroit->id, 'role_id' => $d->role_id))->current();
						if (!$droitExist) {
							$data = array();
							$data['droit_id'] = $btnDeleteDroit->id;
							$data['role_id'] = $d->role_id;
							$data['value'] = 'R';
							$tableDroitConfig->insert($data);
							echo "Droit afficher ajouter pour le bouton 'supprimer une liste' pour le mode $mode, profil : $d->role_id <br>";
							$i++;
						}
					}
					if ($btnSaveDroit) {
						$droitExist = $tableDroitConfig->select(array('droit_id' => $btnSaveDroit->id, 'role_id' => $d->role_id))->current();
						if (!$droitExist) {
							$data = array();
							$data['droit_id'] = $btnSaveDroit->id;
							$data['role_id'] = $d->role_id;
							$data['value'] = 'R';
							$tableDroitConfig->insert($data);
							echo "Droit afficher ajouter pour le bouton 'modifier une liste' pour le mode $mode, profil : $d->role_id <br>";
							$i++;
						}
					}
					if ($btnChampDroit) {
						$droitExist = $tableDroitConfig->select(array('droit_id' => $btnChampDroit->id, 'role_id' => $d->role_id))->current();
						if (!$droitExist) {
							$data = array();
							$data['droit_id'] = $btnChampDroit->id;
							$data['role_id'] = $d->role_id;
							$data['value'] = 'R';
							$tableDroitConfig->insert($data);
							echo "Droit afficher ajouter pour le bouton 'choix champs' pour le mode $mode, profil : $d->role_id <br>";
							$i++;
						}
					}
				}
			}
		}
		echo "Terminer $i lignes creer";
		exit();
	}

	##script creation des doirt par campagn pour les fiche locattaires
	public function creerDroitsOngletFicheParCampagneAction()
	{
		$i = 0;
		$tableDCC = $this->getTableObjet('droit_config_campagne');
		$tableC = $this->getTableObjet('droit_config');
		$tableDE = $this->getTableObjet('droit_elements');
		$tableCamp = $this->getTableObjet('campagnes');

		$campagnes = array();
		$result = $tableCamp->select();
		foreach ($result as $row) {
			$campagnes[$row->id] = $row->nom;
		}

		$elems = $tableDE->select(array('parent_id' => 99));
		foreach ($elems as $elem) {
			//on recup tout les lignes de ce droit de droit_config
			$droitsConfig = $tableC->select(array('droit_id' => $elem->id));
			foreach ($droitsConfig as $row) {
				if ($row->value != 'X') {
					foreach ($campagnes as $idCampagne => $camp) {
						//on verifie si on a deja la ligne existe
						$data = array('role_id' => $row->role_id, 'droit_id' => $row->droit_id, 'idCampagne' => $idCampagne);
						$dc = $tableDCC->select($data)->current();
						if (!$dc) {
							$tableDCC->insert($data);
							echo "Droit creer pour ".$row->role_id." de l'onglet ".$elem->nom." de la campagne $camp<br>";
							$i++;
						}
					}
				}
			}
		}

		echo "Terminer : $i lignes ajouter";
		exit();
	}
	/*****************************************************************************************************************************/
	################################################ MODE FACTURE SERVER SIDE ####################################################
	/*****************************************************************************************************************************/

	## mode Facture server side : chargement entete tableau
	public function afficherfactAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs
			$jsonFactDatatableState = $request->getPost('jsonFactDatatableState', array());
			$typeListe = $request->getPost('typeListe', "");
			$modeConsolide = $request->getPost('modeConsolide', 0);
			$dateDebut = $request->getPost('dateDebut', '');
			$dateFin = $request->getPost('dateFin', '');
			$typeFact = $request->getPost('typeFact', '');

			$options = array('modeConsolide' => $modeConsolide,
							'dateDebut' => $dateDebut,
							'dateFin' => $dateFin,
							'typeFact' => $typeFact,
							'typeLoad' => 'entete',
							);

			$jsonFactDatatableFrom  = 'POST';
			if (empty($jsonFactDatatableState)) {
				$jsonFactDatatableState = $this->getFactureTable()->loadState($typeListe);
				$jsonFactDatatableFrom  = 'BDD';
			}
			//print_r($jsonFactDatatableState);

			$jsonFactDatatableFilter = array_key_exists('filter', $jsonFactDatatableState) ? $jsonFactDatatableState['filter'] : [];

			// Valeurs uniques pour les différents selects
			$selectOptions	= array();

			// Constitution d'une liste des lignes
			$rowsAll = $listeChampsAffiches = array();

			if ($jsonFactDatatableFilter) {
				// Initialisation de la liste des champs
				$formFields     = $this->getFactureTable()->getFields($jsonFactDatatableFilter, $typeListe, array('champsTranslations' => $this->getAllChampsTranslation(), 'champsTable' => $this->getChampsTable(),
				));


				// Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				$listeChampsAffiches    = $this->getFactureTable()->getlisteChampsAffiches($jsonFactDatatableFilter, $formFields);
				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$rowsAll = $this->getFactureTable()->getListeWithAllFields($typeListe, $listeChampsAffiches, array(), $options);

				// Constitution de la liste des options
				if ($rowsAll) {
					foreach ($rowsAll as $_key => $_row) {
						foreach ($_row as $_colName => $_value) {
							if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
								}
								$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
								if (!$_options || !in_array($_value, $_options)) {
									$selectOptions[$_colName][] = $_value;
								}
							} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($_value) {
									$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
									if(!empty($valsArr)) {
										foreach($valsArr as $k => $v) {
											$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
											if (!$_options || !in_array($v, $_options)) {
												$selectOptions[$_colName][] = $v;
											}
										}
									}
								}
							}
						}
					}
				}

				// Tri de ces options dans l'ordre alphabétique
				foreach ($selectOptions as $_colName => $_options) {
					sort($selectOptions[$_colName], SORT_STRING);
				}
			}



			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/modefacturetable')
				->setVariables(array(
					'rows' 		=> array(),
					'test' => "alolo",
					'resaFields' 	=> isset($formFields) ? $formFields['resaFields'] : array(),
					'factFields' 	=> isset($formFields) ? $formFields['factFields'] : array(),
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'				=> 1,
					'jsonFactDatatableState' => $jsonFactDatatableState,
					'selectOptions'	=> $selectOptions,
					'typeListe' => $typeListe,
					'etatsDG' => $tools->getEtatsDG(),
					'champsNonModifiables'	=> $this->getChampsNonModifiable(),
					'config' => $this->getConfigurationTable()->getConfig(1),
				));

			$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'champs' => $listeChampsAffiches,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function getServerJsonDataFactAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');
			$typeListe  = $request->getPost('typeListe', '');
			$modeConsolide = $request->getPost('modeConsolide', 0);
			$dateDebut = $request->getPost('dateDebut', '');
			$dateFin = $request->getPost('dateFin', '');
			$typeFact = $request->getPost('typeFact', '');

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			$options = array('modeConsolide' => $modeConsolide,
							'dateDebut' => $dateDebut,
							'dateFin' => $dateFin,
							'typeFact' => $typeFact,
							);

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('data' => [], 'draw' => 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);
			/*$view = new JsonModel($output);
			$view->setTerminal(true);
			return($view);*/

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonFactDatatableState		= $this->getFactureTable()->loadState($typeListe);
			$jsonFactDatatableFilter	= $jsonFactDatatableState ? $jsonFactDatatableState['filter'] : [];

			if ($jsonFactDatatableFilter && $columns) {
				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getFactureTable()->getFields($jsonFactDatatableFilter, $typeListe, array('champsTranslations' => $this->getAllChampsTranslation(), 'champsTable' => $this->getChampsTable(),
				));

				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$listeChampsAffiches	= array(
					'idLocataire' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
					'idReservation' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
				);

				foreach ($columns as $_key => $_column) {
					$_colName	= $_column['data'];
					if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
						## Recherche du champ dans les différentes listes de champs
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($formFields as $_typeField => $_fields) {
							if ($_typeField == "activeFields") {
								continue;
							}
							$_field = array_key_exists($_colName, $_fields) ? $_fields[$_colName] : null;
							if ($_field) {
								if ($_typeField == 'dynFields') {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->idChamp,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								} else {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->id,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								}
								break;
							}
						}
					}
				}

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where	= "";
				$rowsAll = $this->getFactureTable()->getListeWithAllFields($typeListe, $listeChampsAffiches, $where, $options);


				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);

				if ($rowsAll) {
					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					$selectVals = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
								$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					if ($colDates || !empty($selectVals)) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							if ($colDates) {
								foreach ($colDates as $_colName) {
									$rowValue	= $row[$_colName];
									if ($rowValue && strpos($rowValue, '-') == 2) {
										## Date au format dd-mm-yyyy -> il faut convertir
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $rowValue);
										$row[$_colName]		= "$yyyy-$mm-$dd";
									}
								}
							}
							##Select multiple
							if(!empty($selectVals)) {
								foreach($selectVals as $_colName => $sVals) {
									$rowValue	= $row[$_colName];
									if($rowValue) {
										$rowValueArr = explode(',', $rowValue);
										if(!empty($rowValueArr)) {
											$rowValueNew = '';
											foreach($rowValueArr as $v) {
												$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
												$rowValueNew .= ', ';
											}
											$rowValueNew = substr($rowValueNew, 0, -2);
											if($rowValueNew) {
												$row[$_colName]	= $rowValueNew;
											}
										}
									}
								}
							}
							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}

					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonFactDatatableFilter as $fieldName => $field) {
						$searchTypes[$fieldName]	= $field['type'];
						if (in_array($fieldName, $colRadios)) {
							$searchTypes[$fieldName]	= "text";
						}//traiter les champs radio comme des text
						if (in_array($fieldName, $colCheckbox)) {
							$searchTypes[$fieldName]	= "checkbox";
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));

					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column['name'];
						$value		= $column['search']['value'];
						if ($colName && $column['searchable'] && $value) {
							$searchType	= $searchTypes[$colName];
							if ($searchType == 'date' || $searchType == 'number') {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max)		= explode("|", $value);
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['min']		= $min;
								$searchs[$colName]['max']		= $max;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['text']	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search['min'] && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'number') {
									if ($search['min'] != '' && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] != '' && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}


					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}

				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
			}

			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;

			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function savestatefactAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonDatatableState = $request->getPost('jsonFactDatatableState', array());
			$typeListe = $request->getPost('typeListe', '');

			$this->getFactureTable()->saveState($typeListe, $jsonDatatableState);

			$view = new JsonModel(['success' => true]);
			$view->setTerminal(true);
			return $view;
		}
	}

	private function getChampsNonModifiable()
	{
		$champsNonModifiables = array(
								'idReservation', 'idLocataire', 'idPMS',
								'nomLocataire', 'prenomLocataire', 'etatReservation',
								'campagne', 'programmeEcole', 'sousProgrammeEcole', 'programme', 'sousProgramme',
								'batiment', 'residence',
								'etatIntercontrat',
								'typeLogement1', 'typeLogement2', 'typeLogement3', 'typeLogement4', 'typeLogementAttribue', 'prelevementLoyer',
								'clesPrincipale',
								'logementAncienneResa', 'etatAncienneResa', 'soldeAncienneResa', 'dateProchaineResa', 'etatProchaineResa',
								'dateDebutPF', 'dateFinPF',
							);
		return $champsNonModifiables;
	}


	public function getFactureTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->factureTable) {
			$this->factureTable = new FactureTable($adapter);
		}
		$gl = $this->getGlobalHelper();
		$this->factureTable->setGlobalHelper($gl);
		return $this->factureTable;
	}

	######################################## FIN MODE FACTURE SERVER SIDE ##########################################

	/*****************************************************************************************************************************/
	################################################ MODE PRESTATION SERVER SIDE ####################################################
	/*****************************************************************************************************************************/

	## mode Prestation server side : chargement entete tableau
	public function afficherprestationAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs
			$jsonPrestaDatatableState = $request->getPost('jsonPrestaDatatableState', array());
			$typeListe = $request->getPost('typeListe', "");
			$modeConsolide = $request->getPost('modeConsolide', 0);
			$dateDebut = $request->getPost('dateDebut', '');
			$dateFin = $request->getPost('dateFin', '');
			$typePrestation = $request->getPost('typePrestation', '');

			$options = array('modeConsolide' => $modeConsolide,
							'dateDebut' => $dateDebut,
							'dateFin' => $dateFin,
							'typePrestation' => $typePrestation,
							'typeLoad' => 'entete',
							);

			$jsonPrestaDatatableFrom  = 'POST';
			if (empty($jsonPrestaDatatableState)) {
				$jsonPrestaDatatableState = $this->getPrestationTable()->loadState($typeListe);
				$jsonPrestaDatatableFrom  = 'BDD';
			}
			//print_r($jsonPrestaDatatableState);

			$jsonPrestaDatatableFilter = array_key_exists('filter', $jsonPrestaDatatableState) ? $jsonPrestaDatatableState['filter'] : [];

			// Valeurs uniques pour les différents selects
			$selectOptions	= array();

			// Constitution d'une liste des lignes
			$rowsAll = $listeChampsAffiches = array();

			if ($jsonPrestaDatatableFilter) {
				// Initialisation de la liste des champs
				$formFields     = $this->getPrestationTable()->getFields($jsonPrestaDatatableFilter, $typeListe, array('champsTranslations' => $this->getAllChampsTranslation(), 'champsTable' => $this->getChampsTable(),
				));


				// Constitution de la liste des champs à afficher, avec les champs obligatoires pour le fonctionnement des actions dans les listes
				$listeChampsAffiches    = $this->getPrestationTable()->getlisteChampsAffiches($jsonPrestaDatatableFilter, $formFields);
				// Version rapide de la lecture de la BDD
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$rowsAll = $this->getPrestationTable()->getListeWithAllFields($typeListe, $listeChampsAffiches, array(), $options);

				// Constitution de la liste des options
				if ($rowsAll) {
					foreach ($rowsAll as $_key => $_row) {
						foreach ($_row as $_colName => $_value) {
							if ($listeChampsAffiches[$_colName]['idTypeHtml'] == 3) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
								}
								$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
								if (!$_options || !in_array($_value, $_options)) {
									$selectOptions[$_colName][] = $_value;
								}
							} elseif($listeChampsAffiches[$_colName]['idTypeHtml'] == 18 && $listeChampsAffiches[$_colName]['sourceListe']) {
								$_options	= $selectOptions[$_colName];
								if (trim($_value == "")) {
									$_value = 'null';
									$_value = htmlspecialchars($_value, ENT_QUOTES, 'UTF-8');
									if (!$_options || !in_array($_value, $_options)) {
										$selectOptions[$_colName][] = $_value;
									}
								} elseif($_value) {
									$valsArr = $this->getGlobalHelper()->getSelectMultipleVals($listeChampsAffiches[$_colName]['sourceListe'], $_value);
									if(!empty($valsArr)) {
										foreach($valsArr as $k => $v) {
											$v = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
											if (!$_options || !in_array($v, $_options)) {
												$selectOptions[$_colName][] = $v;
											}
										}
									}
								}
							}
						}
					}
				}

				// Tri de ces options dans l'ordre alphabétique
				foreach ($selectOptions as $_colName => $_options) {
					sort($selectOptions[$_colName], SORT_STRING);
				}
			}



			$htmlViewPart = new ViewModel();
			$htmlViewPart
				->setTerminal(true)
				->setTemplate('reservation/liste/modeprestationtable')
				->setVariables(array(
					'rows' 		=> array(),
					'resaFields' 	=> isset($formFields) ? $formFields['resaFields'] : array(),
					'prestationFields' 	=> isset($formFields) ? $formFields['prestationFields'] : array(),
					'dynFields' 	=> isset($formFields) ? $formFields['dynFields'] : [],
					'i'				=> 1,
					'jsonPrestaDatatableState' => $jsonPrestaDatatableState,
					'selectOptions'	=> $selectOptions,
					'typeListe' => $typeListe,
					'etatsDG' => $tools->getEtatsDG(),
					'champsNonModifiables'	=> $this->getChampsNonModifiable(),
					'config' => $this->getConfigurationTable()->getConfig(1),
				));

			$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'champs' => $listeChampsAffiches,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function getServerJsonDataPrestaAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$conf = $this->getConfigurationTable()->getConfig(1);

		if ($request->isXmlHttpRequest()) {
			$gestId = 1;
			if ($auth->hasIdentity()) {
				$user = $auth->getIdentity();
				$gestId =  $user->getId();
			}
			$draw		= $request->getPost('draw');
			$start		= $request->getPost('start');
			$length		= $request->getPost('length');
			$columns	= $request->getPost('columns');
			$order		= $request->getPost('order');
			$typeListe  = $request->getPost('typeListe', '');
			$modeConsolide = $request->getPost('modeConsolide', 0);
			$dateDebut = $request->getPost('dateDebut', '');
			$dateFin = $request->getPost('dateFin', '');
			$typePrestation = $request->getPost('typePrestation', '');

			## recherche depuis la zone de texte global
			$searchGlobal = $request->getPost('search');
			$searchGlobalVal = "";
			if ($searchGlobal && !empty($searchGlobal) && $searchGlobal['value'] != "") {
				$searchGlobalVal = $searchGlobal['value'];
			}

			$options = array('modeConsolide' => $modeConsolide,
							'dateDebut' => $dateDebut,
							'dateFin' => $dateFin,
							'typePrestation' => $typePrestation,
							);

			## Init des listes
			## ~~~~~~~~~~~~~~~
			$rowsAll	= array();
			$rowsSlice	= array();

			## Init de la sortie
			## ~~~~~~~~~~~~~~~~~
			$output		= array('data' => [], 'draw' => 0 + $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0);
			/*$view = new JsonModel($output);
			$view->setTerminal(true);
			return($view);*/

			## Lecture des descriptions de colonnes et de filtres en BDD
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$jsonPrestaDatatableState		= $this->getPrestationTable()->loadState($typeListe);
			$jsonPrestaDatatableFilter	= $jsonPrestaDatatableState ? $jsonPrestaDatatableState['filter'] : [];

			if ($jsonPrestaDatatableFilter && $columns) {
				## Initialisation de la description des champs des formulaires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$formFields     = $this->getPrestationTable()->getFields($jsonPrestaDatatableFilter, $typeListe, array('champsTranslations' => $this->getAllChampsTranslation(), 'champsTable' => $this->getChampsTable(),
				));

				## Constitution de la liste des champs à afficher, avec les champs obligatoires (pour le fonctionnement des actions sur la liste)
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$listeChampsAffiches	= array(
					'idLocataire' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'idLocataire', 'visible' => false),
					'idReservation' => array('dyn' => 0, 'typeField' => 'resaFields', 'idTypeHtml' => 5, 'table' => 'reservations', 'equivalentSql' => 'id', 'visible' => false),
				);

				foreach ($columns as $_key => $_column) {
					$_colName	= $_column['data'];
					if ($_colName && !array_key_exists($_colName, $listeChampsAffiches)) {
						## Recherche du champ dans les différentes listes de champs
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($formFields as $_typeField => $_fields) {
							if ($_typeField == "activeFields") {
								continue;
							}
							$_field = array_key_exists($_colName, $_fields) ? $_fields[$_colName] : null;
							if ($_field) {
								if ($_typeField == 'dynFields') {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 1,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->idChamp,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								} else {
									$listeChampsAffiches[$_colName] = array(	'dyn' => 0,
															'typeField' => $_typeField,
															'idTypeHtml' => $_field->idTypeHtml,
															'table' => $_field->table,
															'idChamp' => $_field->id,
															'equivalentSql' => $_field->equivalentSql,
															'sourceListe' => $_field->sourceListe,
															'visible' => true);
								}
								break;
							}
						}
					}
				}

				## Version nouvelle de lecture de la BDD
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$where	= "";
				$rowsAll = $this->getPrestationTable()->getListeWithAllFields($typeListe, $listeChampsAffiches, $where, $options);
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nbRowsAll=".count($rowsAll)." rowsAll=".json_encode(array_slice($rowsAll, 0, 2)));


				## Traitement de la partie "server side"
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$output['recordsTotal']		= count($rowsAll);

				if ($rowsAll) {
					## Parcourir la sortie pour corriger les dates au format DD-MM-YYYY
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Construire une liste des champs avec dates
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$colDates	= array();
					$colRadios = array();
					$colNombres = array();
					$colCheckbox = array();
					$colsTypes = array();
					$selectVals = array();
					if ($listeChampsAffiches) {
						foreach ($listeChampsAffiches as $_colName => $_col) {
							if ($_col[idTypeHtml] == 2 || $_col[idTypeHtml] == 19) {
								$colDates[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 9) {
								$colRadios[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 5) {
								$colNombres[]	= $_colName;
							} elseif ($_col[idTypeHtml] == 8) {
								$colCheckbox[]	= $_colName;
							} elseif($_col[idTypeHtml] == 18 && $_col[sourceListe]) {
								$selectVals[$_colName] = $this->getGlobalHelper()->getSelectMultipleVals($_col[sourceListe]);
							}
							$colsTypes[$_colName] = $_col[idTypeHtml];
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : colDates=".json_encode($colDates));

					if ($colDates || !empty($selectVals)) {
						$rowsAll1	= array();
						foreach ($rowsAll as $key => $row) {
							if ($colDates) {
								foreach ($colDates as $_colName) {
									$rowValue	= $row[$_colName];
									if ($rowValue && strpos($rowValue, '-') == 2) {
										## Date au format dd-mm-yyyy -> il faut convertir
										## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
										list($dd, $mm, $yyyy)	= explode("-", $rowValue);
										$row[$_colName]		= "$yyyy-$mm-$dd";
									}
								}
							}

							##Select multiple
							if(!empty($selectVals)) {
								foreach($selectVals as $_colName => $sVals) {
									$rowValue	= $row[$_colName];
									if($rowValue) {
										$rowValueArr = explode(',', $rowValue);
										if(!empty($rowValueArr)) {
											$rowValueNew = '';
											foreach($rowValueArr as $v) {
												$rowValueNew .= !empty($sVals[$v]) ? $sVals[$v] : '';
												$rowValueNew .= ', ';
											}
											$rowValueNew = substr($rowValueNew, 0, -2);
											if($rowValueNew) {
												$row[$_colName]	= $rowValueNew;
											}
										}
									}
								}
							}

							$rowsAll1[]	= $row;
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : count_rowsAll1=".count($rowsAll1)." debut_rowsAll1=".json_encode(array_slice($rowsAll1, 0, 1)));
						$rowsAll	= $rowsAll1;
					}

					## Constitution d'une liste de types de filtres
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$searchTypes	= array();
					foreach ($jsonPrestaDatatableFilter as $fieldName => $field) {
						$searchTypes[$fieldName]	= $field['type'];
						if (in_array($fieldName, $colRadios)) {
							$searchTypes[$fieldName]	= "text";
						}//traiter les champs radio comme des text
						if (in_array($fieldName, $colCheckbox)) {
							$searchTypes[$fieldName]	= "checkbox";
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchTypes=".json_encode($searchTypes));

					## Filtrage dans la table
					## ~~~~~~~~~~~~~~~~~~~~~~
					$searchs	= array();
					foreach ($columns as $key => $column) {
						## Constitution d'une liste de filtres dans la requete Ajax
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$colName	= $column['name'];
						$value		= $column['search']['value'];
						if ($colName && $column['searchable'] && $value) {
							$searchType	= $searchTypes[$colName];
							if ($searchType == 'date' || $searchType == 'number') {
								## Toutes les dates sont au format YYYY-MM-DD, donc triables
								list($min, $max)		= explode("|", $value);
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['min']		= $min;
								$searchs[$colName]['max']		= $max;
							} elseif ($searchType == 'text' || $searchType == 'checkbox') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$searchs[$colName]['text']	= $value;
							} elseif ($searchType == 'select') {
								$searchs[$colName]['colInd']	= $column['data'];
								$searchs[$colName]['type']	= $searchType;
								$explode = explode("|", $value);
								$selectOpt = array();
								foreach ($explode as $sVal) {
									if ($sVal == 'null' || $sVal == " ") {
										$sVal = null;
									}
									$selectOpt[] = $sVal;
								}
								$searchs[$colName][values] = $selectOpt;
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : searchs=".json_encode($searchs));

					$rowsSel	= array();
					if ($searchs || $searchGlobalVal != "") {
						$searchGlobalValSTR = $searchGlobalVal;
						## Parcourir les sorties pour filtrer à la main
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						foreach ($rowsAll as $key => $row) {
							foreach ($searchs as $colName => $search) {
								$rowValue	= $row[$search['colInd']];
								if($colName == 'dureeSejour') {
									$rowValue = trim(str_replace('jours', '', $rowValue));
									$rowValue = trim(str_replace('mois', '', $rowValue));
								}
								if ($search['type'] == 'date') {
									$rowValue = date('Y-m-d', strtotime($rowValue));

									if ($search['min'] && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'number') {
									if ($search['min'] != '' && $rowValue < $search['min']) {
										continue 2;
									}
									if ($search['max'] != '' && $rowValue > $search['max']) {
										continue 2;
									}
								} elseif ($search['type'] == 'text') {
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile
										$contain = false;
										$startWith = false;
										$finishWith = false;

										if (substr($search['text'], -1, 1) == '*' && substr($search['text'], 0, 1) == '*') {
											//contient un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);//on enleve le dernier etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));// on enleve le premier etoile
											$contain = true;
										} elseif (substr($search['text'], 0, 1) == '*') {
											//commence avec etoile
											$search['text'] = substr($search['text'], 1, strlen($search['text']));
											$finishWith = true;
										} elseif (substr($search['text'], -1, 1) == '*') {
											//fini par un etoile
											$search['text'] = substr($search['text'], 0, strlen($search['text']) - 1);
											$startWith = true;
										} else {
											$startWith = true;
										}


										if ($contain && stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
										if ($startWith && stripos($rowValue, $search['text']) !== 0 && $search['text'] != null) {
											continue 2;
										}

										if ($finishWith && !((substr(strtolower($rowValue), -strlen($search['text'])) === strtolower($search['text']))) && $search['text'] != null) {
											continue 2;
										}
									} else {
										if (stripos($rowValue, $search['text']) === false && $search['text'] != null) {
											continue 2;
										}
									}
									if ($search['text'] == null && $rowValue) {
										continue 2;
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'select') {
									if(!empty($selectVals[$colName])) {
										$rowValueArr = explode(', ', $rowValue);
										if(!empty($rowValueArr)) {
											$found = false;
											foreach($rowValueArr as $rowVal) {
												if (in_array($rowVal, $search['values'])) {
													$found = true;
												}
											}
											if(!$found) {
												continue 2;
											}
										} else {
											if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
												continue 2;
											}
										}
									} else {
										if (/*!$rowValue || */in_array($rowValue, $search['values']) === false) {
											continue 2;
										}
									}
									//prise en compte des valeurs null si on filtre sur null
								} elseif ($search['type'] == 'checkbox') {
									$rowValue = $rowValue ? 'oui' : 'non';
									if (/*!$rowValue || */stripos($rowValue, $search['text']) === false && $search['text'] != null) {
										continue 2;
									}
								}
							}
							## Recherche global
							if ($searchGlobalVal != "") {
								$trouve = false;
								$contain = false;
								$startWith = false;
								$finishWith = false;

								if ($conf->filtreAverEtoile == 1) {
									if (substr($searchGlobalValSTR, -1, 1) == '*' && substr($searchGlobalValSTR, 0, 1) == '*') {
										//contient un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);//on enleve le dernier etoile
										$searchGlobalVal = substr($searchGlobalVal, 1, strlen($searchGlobalVal));// on enleve le premier etoile
										$contain = true;
									} elseif (substr($searchGlobalValSTR, 0, 1) == '*') {
										//commence avec etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 1, strlen($searchGlobalValSTR));
										$finishWith = true;
									} elseif (substr($searchGlobalValSTR, -1, 1) == '*') {
										//fini par un etoile
										$searchGlobalVal = substr($searchGlobalValSTR, 0, strlen($searchGlobalValSTR) - 1);
										$startWith = true;
									} else {
										$startWith = true;
									}
								}

								foreach ($columns as $key => $column) {
									$rowValue	= $row[$column['name']];
									if ($conf->filtreAverEtoile == 1) {
										//prise en compte de mode de recherche avec etoile

										if ($contain) {
											if (stripos($rowValue, $searchGlobalVal) !== false) {
												$trouve = true;
											}
											if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
												$trouve = true;
											}
										} elseif ($finishWith) {
											if ($searchGlobalVal && ((substr(strtolower($rowValue), -strlen($searchGlobalVal)) === strtolower($searchGlobalVal)))) {
												$trouve = true;
											}
										} elseif ($startWith) {
											if ($searchGlobalVal && stripos($rowValue, $searchGlobalVal) === 0) {
												$trouve = true;
											}
										}
									} else {
										if (stripos($rowValue, $searchGlobalVal) !== false) {
											$trouve = true;
										}
										if ($searchGlobalVal == " " && ($rowValue == "" || $rowValue == null)) {
											$trouve = true;
										}
									}
								}

								if (!$trouve) {
									continue;
								}
							}
							$rowsSel[]	= $row;
						}
					} else {
						$rowsSel	= $rowsAll;
					}


					## Construire l'ordre de tri avec le nom des colonnes (plutôt que l'index)
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$sortOrder	= array();
					if ($order) {
						foreach ($order as $_key => $_order) {
							$_colInd	= $_order['column'];
							$_colName	= $columns[$_colInd]['name'];
							if ($_colInd && $_colName) {
								$idType = !empty($colsTypes[$_colName]) ? $colsTypes[$_colName] : 0;
								$sortOrder[]	= array('colName' => $_colName, 'dir' => $_order['dir'], 'idType' => $idType);
							}
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : sortOrder=".json_encode($sortOrder));

					## Tri de la table
					## ~~~~~~~~~~~~~~~
					uasort($rowsSel, function ($a, $b) use ($sortOrder, $colNombres) {
						## On ne s'occupe que de la première colonne pour l'instant
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$_sortOrder	= reset($sortOrder);
						$_colName	= $_sortOrder['colName'];
						if ($_sortOrder['dir'] == "asc") {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] <= $b[$_colName];
							} else {
								if ($_sortOrder['idType'] == 2 && (!$a[$_colName] || !$b[$_colName])) {
									//mettre les dates vide à la fin
									if (!$a[$_colName]) {
										return 1;
									} else {
										return -1;
									}
								} else {
									return strcasecmp($a[$_colName], $b[$_colName]);
								}
							}
						} else {
							if (in_array($_colName, $colNombres)) {
								return $a[$_colName] >= $b[$_colName];
							} else {
								return strcasecmp($b[$_colName], $a[$_colName]);
							}
						}
					});
				} else {
					$rowsSel	= $rowsAll;
				}

				$output['recordsFiltered']	= count($rowsSel);
				$rowsSlice			= $length == -1 ? array_slice($rowsSel, $start) : array_slice($rowsSel, $start, $length);
			}


			## Sortie en tableau
			## ~~~~~~~~~~~~~~~~~
			$output['data']	= $rowsSlice;
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : nbRowsSlice=".count($rowsSlice)." debut_rowsSlice=".json_encode(array_slice($rowsSlice, 0, 1)));

			$view = new JsonModel($output);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function savestateprestationAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] :");
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// Lecture des descriptions des champs des logements
			$jsonDatatableState = $request->getPost('jsonPrestaDatatableState', array());
			$typeListe = $request->getPost('typeListe', '');

			$this->getPrestationTable()->saveState($typeListe, $jsonDatatableState);

			$view = new JsonModel(['success' => true]);
			$view->setTerminal(true);
			return $view;
		}
	}

	public function getPrestationTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->prestationTable) {
			$this->prestationTable = new PrestaTable($adapter);
		}
		return $this->prestationTable;
	}

	public function prestareviserAction()
	{
		$request = $this->getRequest();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] POST=".json_encode($_POST));
		if ($request->isXmlHttpRequest()) {
			$keysPresta		= $request->getPost('data');//ids des résa
			$prestaModeRevision	= $request->getPost('prestaModeRevision');
			$prestaModeRevisionTaux	= $request->getPost('prestaModeRevisionTaux');
			$prestaModeRevisionMontantFixe	= $request->getPost('prestaModeRevisionMontantFixe');
			$prestaOperation	= $request->getPost('prestaOperation');
			$prestaArrondi		= $request->getPost('prestaArrondi');
			$success		= false;
			$msg			= "";

			## Vérification des paramètres
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if (empty($keysPresta)) {
				$msg = "Liste de prestations ne doit pas être vide";
			}

			if ($prestaModeRevisionTaux && $prestaModeRevisionMontantFixe) {
				$msg = "On ne peut pas calculer une révision avec un taux et un montant fixe";
			}
			if (!$prestaModeRevisionTaux && !$prestaModeRevisionMontantFixe) {
				$msg = "Il faut définir un taux de révision ou un montant fixe";
			}

			## Traitement des révisions de tarif des prestations
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if (!$msg) {
				list($success, $msg)	= $this->getPrestationTable()->reviserPresta($keysPresta, $prestaOperation, $prestaModeRevision, $prestaModeRevisionTaux, $prestaModeRevisionMontantFixe, $prestaArrondi);
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : success=$success msg=$msg");
			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}
	public function prestaannulerrevisionAction()
	{
		$request = $this->getRequest();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR]");
		if ($request->isXmlHttpRequest()) {
			$keysPresta		= $request->getPost('data');//ids des résa
			$success		= false;
			$msg			= "";

			## Vérification des paramètres
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if (empty($keysPresta)) {
				$msg = "Liste de prestations ne doit pas être vide";
			}

			## Traitement des révisions de tarif des prestations
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if (!$msg) {
				list($success, $msg)	= $this->getPrestationTable()->annulerRevisionPresta($keysPresta);
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : success=$success msg=$msg");
			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	######################################## FIN MODE PRESTATION SERVER SIDE ##########################################

	public function getConfigMailsTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->configMailsTable) {
			$this->configMailsTable = new ConfigMailsTable($adapter);
		}
		return $this->configMailsTable;
	}

	//Retourn le profil connecté
	public function getRoleId()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$role_id = $this->getUserTable()->getUserProfil($gestId)->role_id;
		return $role_id;
	}

	## Vérifie si une tal a un accès vamable pour une campagne donnée par profil
	public function getTabsDroitParCampagne($idCampagne, $tab)
	{
		$role_id = $this->getRoleId();

		$globalHelper = $this->getGlobalHelper();
		$droitsTabCamp = $globalHelper->getTabsParCampEtProfil($idCampagne, $role_id);
		$allowdCamp = array_key_exists($tab, $droitsTabCamp);
		return $allowdCamp;
	}

	##retourn la liste des tabs accessible d'un profil par campagne
	public function getAllAlowedTabsByCamp($idCampagne)
	{
		$role_id = $this->getRoleId();
		$globalHelper = $this->getGlobalHelper();
		$droitsTabCamp = $globalHelper->getTabsParCampEtProfil($idCampagne, $role_id);
		return $droitsTabCamp;
	}

	## chargement de la liste des campagne destination lors de changement de la campagne de dossier
	public function loadCampagnesAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$mode = $request->getPost('mode', '');

			$msg = "";
			$success = true;
			$options = array();

			if (!empty($ids)) {
				if ($mode == 'dp') {
					$campagnes = $this->getCampagneTable()->getCampagnesByTypeCode('dp');
				} else {
					$campagnes = $this->getCampagneTable()->getCampagnesByTypeCode();
				}
				foreach ($campagnes as $row) {
					$options[$row->id] = $row->nom;
				}
			} else {
				$msg = "Aucun ligne coché";
				$success = false;
			}
			if (empty($options)) {
				$msg = "Aucune campagne trouvée";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'options' => $options,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## chargement de la liste des programme lié à la campagne choisi
	public function loadProgrammesDeCampagneAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idCampagne = $request->getPost('idCampagne', array());

			$msg = "";
			$success = true;
			$options = array();

			if (!empty($idCampagne)) {
				$rows = $this->getProgrammeTable()->getProgrammeByCampagne($idCampagne);
				foreach ($rows as $row) {
					$options[$row->id] = $row->nom;
				}
			} else {
				$msg = "Aucun campagne choisie";
				$success = false;
			}
			if (empty($options)) {
				$msg = "Aucun programme trouvé";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'options' => $options,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## action validation changement campagne
	public function validerChangementCampagneAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$idCampagne = $request->getPost('idCampagne', 0);//id campagne destination
			$mode = $request->getPost('mode', '');
			$dupliquerDossier = $request->getPost('dupliquerDossier', '');
			$archiverDossier = $request->getPost('archiverDossier', '');
			$idProgramme = $request->getPost('idProgramme', 0);//idProgramme destination
			$modifierSiteDemande = $request->getPost('modifierSiteDemande', '');//transfert de la demande depuis le site par défaut vers le sita campagne

			$msg = "";
			$success = true;
			$msgErrors = $msgSuccess = "";
			if (!empty($ids) && $idCampagne) {
				//on lance que les prestation facturé en mode de paiement Ticket
				$options = array('dupliquerDossier' => $dupliquerDossier, 'archiverDossier' => $archiverDossier, 'idProgramme' => $idProgramme, 'modifierSiteDemande' => $modifierSiteDemande);
				$return = $this->lancerChangementCampagne($ids, $idCampagne, $mode, $options);

				if (!empty($return['error'])) {
					$msgErrors = implode('<br>', $return['error']);
					$success = false;
					if (!empty($return['success'])) {
						$msgSuccess = implode('<br>', $return['success']);
					}
				} else {
					$msg = 'Changement bien fait';
				}
			} else {
				$msg = !$idCampagne ? "Aucune campagne choisi" : "Aucun ligne coché";
				$success = false;
			}

			$view = new JsonModel(array(
				'success' => $success,
				'msg' => $msg,
				'msgSuccess' => $msgSuccess,
				'msgErrors' => $msgErrors,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	## fonction de changement des campagnes
	public function lancerChangementCampagne($ids, $idNouvelleCampagne, $mode = 'resa', $options = array())
	{
		$return = array();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$tableLoc = $this->getTableObjet('locataires');
		$tableResa = $this->getTableObjet('reservations');
		$tableDp = $this->getTableObjet('domiciliations');
		$tableVD = $this->getTableObjet('valeurs_dynamiques');
		$tableCF = $this->getTableObjet('champs_formulaires');
		$tableCartes = $this->getTableObjet('cartes');

		$dupliquerDossier = !empty($options['dupliquerDossier']) ? $options['dupliquerDossier'] : '';
		$archiverDossier = !empty($options['archiverDossier']) ? $options['archiverDossier'] : '';
		$idProgramme = !empty($options['idProgramme']) ? $options['idProgramme'] : '';
		$modifierSiteDemande = !empty($options['modifierSiteDemande']) ? $options['modifierSiteDemande'] : '';

		foreach ($ids as $idLigne) {
			$table = null;
			$champValDyn = '';
			if ($mode == 'dp') {
				$table = $tableDp;
				$champValDyn = 'idDp';
			} elseif ($mode == 'resa') {
				$table = $tableResa;
				$champValDyn = 'idReservation';
			}
			if (!$table) {
				$return['error'][] = "Aucun mode fournis";
			}

			$row = $table->select(array('id' => $idLigne))->current();

			$valeursObjArr = array();

			if ($row) {
				$loc = $tableLoc->select(array('id' => $row->idLocataire))->current();
				if ($row->idCampagne != $idNouvelleCampagne) {
					$idNewRow = null;
					if ($mode == "dp") {
						if ($dupliquerDossier == '1') {
							## on vérifie les champs obligatoire archivage si ils sont bien rempli
							if ($archiverDossier == '1') {
								$ret = $this->checkChampsObligatoireArchivage($row->idCampagne, $idLigne);
							} else {
								$ret = array('allFielObligatoireArchiveOk' => true);
							}
							if($ret['allFielObligatoireArchiveOk']) {
								$newRowData = get_object_vars($row);
								// Si la DP est active, copier les champs de la DP et supprimer l'état de l'ancienne DP | Sinon ne pas copier les champs de la DP
								if ($newRowData['etat'] == '1') {
									unset($newRowData['id']);
									$newRowData['idCampagne'] = $idNouvelleCampagne;
									$newRowData['idAncienneDP'] = $idLigne;
									$dir = getcwd().'/public/docs/locataires/'.$newRowData['idLocataire'];
									if ($newRowData['docName'] && file_exists($dir."/".$newRowData['docName'])) {
										$docNameNew = 'dp-'.time().'-'.$newRowData['docName'];
										copy($dir."/".$newRowData['docName'], $dir."/".$docNameNew);
										$newRowData['docName'] = $docNameNew;
									}
									//print_r($newRowData);exit();
									$table->insert($newRowData);
									$table->update(array('etat' => null), array('id' => $idLigne));
								} else {
									$newRowDpInactif = [];
									$newRowDpInactif['idLocataire'] = $newRowData['idLocataire'];
									$newRowDpInactif['idCampagne'] = $idNouvelleCampagne;
									$newRowDpInactif['idAncienneDP'] = $idLigne;
									$table->insert($newRowDpInactif);
								}

								$idNewRow = $table->lastInsertValue;

								$log = new Logs();
								$log->dateOperation = date('Y-m-d H:i:s');
								$log->idGestionnaire = $gestId;
								$log->operation = "BO changement campagne : duplication DP $idLigne en $idNewRow après de ".$loc->nom." ".$loc->prenom;
								$log->dataBefore = array();
								$log->dataAfter = array();
								$log->tableName = "domiciliations";
								$log->idReservation = null;
								$log->idLocataire = $row->idLocataire;
								$this->getLogsTable()->saveLogs($log);

								$table->update(array('idNouvelleDp' => $idNewRow), array('id' => $idLigne));

								if ($newRowData['etat'] == '1') {
									##on UPDATE l'idDP dans la table carte pour avoir celui de la nouvelle
									$tableCartes->update(array('idDp' => $idNewRow), array('idDp' => $idLigne));
								}

								if ($archiverDossier == '1') {
									$table->update(array('archive' => '1'), array('id' => $idLigne));

									$log = new Logs();
									$log->dateOperation = date('Y-m-d H:i:s');
									$log->idGestionnaire = $gestId;
									$log->operation = "BO changement campagne : Archivage domiciliation $idLigne de ".$loc->nom." ".$loc->prenom;
									$log->dataBefore = array('archive' => '0');
									$log->dataAfter = array('archive' => '1');
									$log->tableName = "domiciliations";
									$log->idReservation = null;
									$log->idLocataire = $row->idLocataire;
									$this->getLogsTable()->saveLogs($log);

								}
							} elseif(!empty($ret['msgErrors'])) {
								foreach($ret['msgErrors'] as $err) {
									$return['error'][] = $err." : domiciliation $idLigne de ".$loc->nom." ".$loc->prenom;
								}
							}
						} else {
							$table->update(array('idCampagne' => $idNouvelleCampagne), array('id' => $idLigne));
							$log = new Logs();
							$log->dateOperation = date('Y-m-d H:i:s');
							$log->idGestionnaire = $gestId;
							$log->operation = "BO changement campagne : de DP $idLigne de ".$loc->nom." ".$loc->prenom;
							$log->dataBefore = array('idCampagne' => $row->idCampagne);
							$log->dataAfter = array('idCampagne' => $row->idNouvelleCampagne);
							$log->tableName = "domiciliations";
							$log->idReservation = null;
							$log->idLocataire = $row->idLocataire;
							$this->getLogsTable()->saveLogs($log);
						}
					} else {
						$passer = true;
						$siteChanged = false;
						$upDataResa = array('idCampagne' => $idNouvelleCampagne);
						if($idProgramme) {
							$upDataResa['idProgramme'] = $idProgramme;
							$upDataResa['idSousProgramme'] = $idProgramme;

							if($modifierSiteDemande == '1') {
								//on vérifie si le site demande est différent de site campagne
								$r = $this->getTable("programme_campagne")->select(array('idProgramme' => $idProgramme, 'idCampagne' => $idNouvelleCampagne))->current();
								if ($r && $r->idResidence) {
									$site = $this->getResidencesTable()->getResidence($r->idResidence);
									$codeSiteNew = $site ? $site->idPMS : '';
									if($codeSiteNew && $codeSiteNew != $row->codeSite) {
										## on crée la nouvelle demande sur le nouveau site
										try {
											$this->ajouterDemandeBredea($idLigne, $codeSiteNew);
											$siteChanged = true;
										} catch(\Exception $ex) {
											$return['error'][] = "Erreur création nouvelle demande $idLigne de ".$loc->nom." ".$loc->prenom;
											$passer = false;
										}
										## on archive l'ancienne demande
										$resa = $this->getResaTable()->getResa($idLigne);
										if($resa->idPMS != $row->idPMS) {
											$cData = array('numDemande' => $resa->idPMS, 'typre' => $resa->typre, 'codeSite' => $resa->codeSite);
											$cData['type'] = 'demande';
											$archive = $this->archiverBredea($cData, $resa->idApiPms ?: 1);
											if(!$archive) {
												$return['error'][] = "Erreur archivage demande $idLigne de ".$loc->nom." ".$loc->prenom;
											}
										}
									}
								}
							}
						}
						if(!$passer) {
							continue;
						}
						$table->update($upDataResa, array('id' => $idLigne));

						$log = new Logs();
						$log->operation = "BO changement campagne : de la résa $idLigne de ".$loc->nom." ".$loc->prenom;
						if($modifierSiteDemande == '1' && $siteChanged) {
							$log->operation = "BO changement campagne avec changement site demande : de la résa $idLigne de ".$loc->nom." ".$loc->prenom;
						}

						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = $gestId;
						$log->operation = "BO changement campagne : de la résa $idLigne de ".$loc->nom." ".$loc->prenom;
						$log->dataBefore = array('idCampagne' => $row->idCampagne);
						$log->dataAfter = array('idCampagne' => $row->idNouvelleCampagne);
						$log->tableName = "reservations";
						$log->idReservation = $idLigne;
						$log->idLocataire = $row->idLocataire;
						$this->getLogsTable()->saveLogs($log);
					}

					$select = $tableCF->getSql()->select();
					$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
					$select->where(array('formulaires.idCampagne' => $idNouvelleCampagne));
					$cRows = $tableCF->selectWith($select);
					$champsIds = array();
					$champsForms = array();
					foreach ($cRows as $champ) {
						$champsIds[$champ->id] = $champ->id;
						$champsForms[$champ->id] = $champ->idFormulaire;
					}

					$select = $tableVD->getSql()->select();
					$select->join('champs_formulaires', 'champs_formulaires.id = valeurs_dynamiques.idChamp', array('idVD' => 'id', 'idFormulaire', 'equivalentSql'));
					$select->where(array('valeurs_dynamiques.'.$champValDyn => $idLigne,
										'valeurs_dynamiques.idLocataire' 	=> $row->idLocataire));
					$vdRows = $tableVD->selectWith($select);

					foreach ($vdRows as $vd) {
						//on ne copie pas les champs de formulaire situation entree
						$continuer = true;
						if ($mode == "dp" && $dupliquerDossier == '1') {
							$idFormANePasCopier = $this->getFormSitSortie($row->idCampagne);
							if ($vd->idFormulaire == $idFormANePasCopier) {
								$continuer = false;
							}
						}
						if ($continuer && !in_array($vd->idChamp, $champsIds)) {

							//on corrige l'idChamp avec le bonne, selon la campagne de la ligne
							//on cherche le bon champ
							$select = $tableCF->getSql()->select();
							$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFormulaire' => 'id', 'idCampagne'));
							$select->where(array('formulaires.idCampagne' => $idNouvelleCampagne,
												'champs_formulaires.equivalentSql' => $vd->equivalentSql));
							if ($mode == "dp" && $dupliquerDossier == '1') {
								$select->where(array('formulaires.afficherEnResa' => 1));
							}
							$bonChamp = $tableCF->selectWith($select)->current();
							if ($bonChamp) {
								//on verifie si existe deja, on supprime la ligne du mauvais
								// sinon on update idChamp avec le bon

								$vdRow = $tableVD->select(array('idChamp' => $bonChamp->id, $champValDyn => $idLigne, 'idLocataire' => $row->idLocataire))->current();
								if (!$vdRow) {
									//maj idChamp
									if ($idNewRow > 0) {
										$oldVD = $tableVD->select(array('id' => $vd->id))->current();
										if ($oldVD) {
											$newVDData = get_object_vars($oldVD);
											unset($newVDData['id']);
											$newVDData['idChamp'] = $bonChamp->id;
											$newVDData[$champValDyn] = $idNewRow;
											$tableVD->insert($newVDData);
											$newVDData['id'] = $tableVD->lastInsertValue;
											$valeursObjArr[] = array('insert' => $newVDData);
										}
									} else {
										$tableVD->update(array('idChamp' => $bonChamp->id), array('id' => $vd->id));
										$dataUp = $vd;
										$dataUp->idChamp = $bonChamp->id;
										$valeursObjArr[] = array('update' => $dataUp);
									}
								}
							}
						}
					}

					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					//$log->idLocataire = $idLocataire;
					//if($valeursObj->idReservation) $log->idReservation = $valeursObj->idReservation;
					$log->operation = "BO : changement campagne (maj valeurs dynamiques) dossier : ".$loc->nom.' '.$loc->prenom;
					$log->dataBefore = array();
					$log->dataAfter = $valeursObjArr;
					$log->tableName = "valeurs_dynamiques";
					$this->getLogsTable()->saveLogs($log);

					//$return['success'][] = "Campagne bien changé pour ".$loc->nom.' '.$loc->prenom;
				} else {
					$return['error'][] = "La ligne $idLigne(".$loc->nom.' '.$loc->prenom.") a déjà la même campagne";
				}
			} else {
				$return['error'][] = "Ligne $idLigne non trouvé";
			}
		}

		return $return;
	}


	public function checkChampsObligatoireArchivage($idCampagne, $idDp)
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$allFielObligatoireArchiveOk = true;

		// pour chaque reservation on regarde si on a des champs obligatoire non rempli
		$formulaires = $this->getTableObjet('formulaires')
		->select(array('idCampagne' => $idCampagne))->toArray();

		$champsArchiveNotOk = [];
		$msgErrors = [];
		if (count($formulaires) > 0 && $idDp) {
			$dp = $this->getDomiciliationsTable()->getDomiciliationById($idDp);
			$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($dp->idLocataire, $adapter, 0, $idDp);
			$dpArr = get_object_vars($dp);
			unset($dpArr['id']);
			$locAllInfosObj = array_merge($locAllInfosObj, $dpArr);

			foreach ($formulaires as $key => $f) {
				$champs_formulaires = $this->getTableObjet('champs_formulaires')
				->select(array('idFormulaire' => $f['id'], 'obligatoireArchivage' => '1', 'active' => '1'))
				->toArray();

				if (count($champs_formulaires) > 0) {

					foreach ($champs_formulaires as $key => $cf) {
						// on vérifie si on a une valeur
						if($cf['nature'] == 'libre') {
							$vd = $this->getTableObjet('valeurs_dynamiques')
							->select(array('idChamp' => $cf['id'], 'idDp' => $idDp))->current();
							if (!$vd || $vd->valeur == '') {
								$champsArchiveNotOk[$cf->id] = $cf;
								$msgErrors[] = "Champ ".$cf['libelle']." obligatoire archivage vide";
							}
						} elseif($cf['nature'] == 'standard') {
							if(array_key_exists($cf['equivalentSql'], $locAllInfosObj)) {
								$valChamp = $locAllInfosObj[$cf['equivalentSql']];
								if($valChamp == null || $valChamp == '' || ($cf['idType'] == 2 && substr($valChamp, 0, 2) == '00')) {
									$champsArchiveNotOk[$cf->id] = $cf;
									$msgErrors[] = "Champ ".$cf['libelle']." obligatoire archivage vide";
								}
							}
						}
					}
				}
			}
		}
		if (count($champsArchiveNotOk) > 0) {
			$allFielObligatoireArchiveOk = false;
		}

		return array('allFielObligatoireArchiveOk' => $allFielObligatoireArchiveOk, 'msgErrors' => $msgErrors);
	}

	## export la liste des dispo
	public function ajaxcsvdispoAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('idsLogements', array());
			$dateDebut = $request->getPost('dateDebut', null);
			$dateFin = $request->getPost('dateFin', null);
			$session = new Container('csvdispo');

			$session->dateDebut = $dateDebut;
			$session->dateFin = $dateFin;

			$data = array();
			$header = array('ID', 'NOM', 'NUMERO', 'TYPE LOGEMENT', 'BATIMENT', 'RESIDENCE');

			$tableLogement = $this->getTableObjet('logements');
			$select = $tableLogement->getSql()->select();
			$select->join('batiments', 'batiments.id = logements.idBatiment', array('idBatiment' => 'id', 'batiment' => 'nom'));
			$select->join('residences', 'residences.id = batiments.idResidence', array('idResidence' => 'id', 'residence' => 'nom'));
			$select->join('type_logement', 'type_logement.id = logements.idTypeLogement', array('idTL' => 'id', 'typeLogement' => 'nom'));
			$select->where->in('logements.id', $ids);
			$result = $tableLogement->selectWith($select);
			foreach ($result as $row) {
				$data[] = array($row->id,
								utf8_decode($row->nom),
								$row->numero,
								utf8_decode($row->typeLogement),
								utf8_decode($row->batiment),
								utf8_decode($row->residence),
								);
			}

			$session->data = $data;
			$session->header = $header;

			$view = new JsonModel(array(
						'success' => true,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	## action d'export des logements dispo
	public function exportdispoAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$session = new Container('csvdispo');
		$data = !empty($session->data) ? $session->data : array();
		$header = !empty($session->header) ? $session->header : array();
		$dateDebut = !empty($session->dateDebut) ? $session->dateDebut : '';
		$dateFin = !empty($session->dateFin) ? $session->dateFin : '';

		$name = "Liste des logements disponible";
		if ($dateDebut) {
			$name .= " du ".date('d-m-Y', strtotime($dateDebut));
		}
		if ($dateFin) {
			$name .= " à ".date('d-m-Y', strtotime($dateFin));
		}
		$name .= '__';

		return $this->outputExcel($data, $header, $name);
	}

	public function demPaiementEmailAction()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$success = false;

		$request = $this->getRequest();
		if ($request->isPost()) {
			$idResa = (int)$request->getPost('idResa');
			$demPaiementEmail = $request->getPost('demPaiementEmail');
			$montantPaiementEmail = (int)$request->getPost('montantPaiementEmail');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa demPaiementEmail=$demPaiementEmail montantPaiementEmail=$montantPaiementEmail");

			if ($idResa) {
				try {
					$resa = $this->getResaTable()->getResa($idResa);
					if ($resa) {
						$success = true;
						$this->getResaTable()->updateResa(array('demPaiementEmail' => $demPaiementEmail, 'montantPaiementEmail' => $montantPaiementEmail), array('id' => $idResa));
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa exception=".$ex->getMessage());
				}
			}

			$view = new JsonModel(array(
				'success'	=> $success,
						  'htmlOPLoc'	=> $htmlOutputLoc,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## dé-archivage réservation
	public function deArchiverResaAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('ids', array());
			$idsToCreate = array();

			$success = true;
			$msg = $msgSuccess = $msgErrors = $toCreateMsg = "";
			$tableResa = $this->getTableObjet('reservations');
			foreach ($idsResa as $idResa) {
				$deArchiverWl = false;
				$deArchiverPMS = false;
				$select = $tableResa->getSql()->select();
				$select->join('locataires', 'reservations.idLocataire = locataires.id', array('idLocataire' => 'id', 'nomLocataire' => 'nom', 'prenomLocataire' => 'prenom'), 'LEFT');
				$select->where(array('reservations.id' => $idResa, /*'reservations.archive'=>'1'*/));
				$resa = $tableResa->selectWith($select)->current();
				//si demande ou parti, on le désarchive, sinon on vérifie le choix fait, si on annule ou on crée une nouvelle demande
				//on vérifie la disponibilité de logement, si il est encore dispo, on dé-archive
				$isDispo = true;
				if($resa->idLogement) {
					if($resa->dateDepart && substr($resa->dateDepart, 0, 2) != '00') {
						$isOccupe = $this->getResaTable()->checkDisponibilite($resa->dateArrivee, $resa->dateDepart, $resa->idLogement, $idResa);//false => dispo
					} else {
						$isOccupe = $this->getResaTable()->checkStartDate($resa->dateArrivee, $resa->idLogement, $idResa, array(2, 3, 7, 15));//false => dispo
					}

					$isDispoArrivee = $this->checkDisponibiliteLogementBredea($resa->id, $resa->dateArrivee);
					$isDispoDepart = true;
					if($resa->dateDepart && substr($resa->dateDepart, 0, 2) != '00') {
						$isDispoDepart = $this->checkDisponibiliteLogementBredea($resa->id, $resa->dateDepart);
					}
					if($isOccupe || !$isDispoArrivee || !$isDispoDepart) {
						$isDispo = false;
					}
				}

				if (($resa->numDossier && $resa->etat != 6 && !$isDispo) || ($resa->etat != 6 && $resa->idLogement > 0 && !$isDispo)) {
					$idsToCreate[] = $idResa;
					$toCreateMsg .= "- $resa->nomLocataire $resa->prenomLocataire<br>";
				} elseif ($resa) {
					$deArchiverWl = true;
					$deArchiverPMS = true;
				}
				if ($deArchiverWl) {
					$this->getResaTable()->updateResa(array('archive' => '0'), array('id' => $idResa));

					### save logs
					$log = new Logs();
					$log->dateOperation = date('Y-m-d H:i:s');
					$log->idGestionnaire = $gestId;
					$log->operation = "BO Dé-archivage réservation $idResa";
					$log->dataBefore = array('archive' => '1');
					$log->dataAfter = array('archive' => '0');
					$log->tableName = "reservations";
					$log->idReservation = $idResa;
					$log->idLocataire = $resa->idLocataire;
					$this->getLogsTable()->saveLogs($log);

					$msgSuccess .= "Réservation bien dé-archivée pour $resa->nomLocataire $resa->prenomLocataire<br>";
				}

				if ($deArchiverPMS) {
					$deArchiver = $this->desarchiverPMS($idResa);
					if (!$deArchiver) {
						$msgErrors .= "Dossier pas dé-archivé côté PMS pour $resa->nomLocataire $resa->prenomLocataire<br>";
					}
				}
			}

			if ($msgErrors != "") {
				$success = false;
			}
			if ($msgErrors == "" && $msgSuccess == "") {
				$msg = "Validation bien faite";
			}

			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'msgSuccess' => $msgSuccess,
						'msgErrors' => $msgErrors,
						'avecLogement' => sizeof($idsToCreate) > 0 ? true : false,
						'idsToCreate' => implode(',', $idsToCreate),
						'toCreateMsg' => $toCreateMsg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## action pour créer de nouvelle demande depuis un dossier, lors de dé-archivage
	public function createNewDemandeAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('ids', array());
			$idsToCreate = array();

			$success = true;
			$msg = $msgSuccess = $msgErrors = "";

			foreach ($idsResa as $idResa) {
				$deArchiverWl = false;
				$deArchiverPMS = false;
				$resa = $this->getResaTable()->getResaEtLoc($idResa, true);
				if ($resa) {
					$ret = $this->createNewResaFrom($idResa);
					if ($ret == 'ok') {
						$msgSuccess .= "Nouvelle demande de réservation bien crée pour $resa->nomLocataire $resa->prenomLocataire<br>";
					} else {
						$msgErrors .= "Demande bredea pas créer pour $resa->nomLocataire $resa->prenomLocataire<br>";
					}
				}
			}

			if ($msgErrors != "") {
				$success = false;
			}
			if ($msgErrors == "" && $msgSuccess == "") {
				$msg = "Validation bien faite";
			}

			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'msgSuccess' => $msgSuccess,
						'msgErrors' => $msgErrors,
						'avecLogement' => sizeof($idsToCreate) > 0 ? true : false,
						'idsToCreate' => implode(',', $idsToCreate),
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	/**
	*@param int : idResa
	*@return bool
	*@desc : dé-archivage dossier PMS
	*/
	private function desarchiverPMS($idResa)
	{
		$ret = false;

		$pms = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
		$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();

		if (is_object($pms)) {
			$cData = array();
			if ($resa->numDossier && $resa->codeSite) {
				$cData = array('numDossier' => $resa->numDossier, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
				$cData['type'] = 'dossier';
			} elseif ($resa->numResa && $resa->codeSite) {
				$cData = array('numResa' => $resa->numResa, 'codeSite' => $resa->codeSite, 'typre' => $resa->typre);
				$cData['type'] = 'resa';
			} elseif ($resa->idPMS) {
				$cData = array('numDemande' => $resa->idPMS, 'typre' => $resa->typre);
				$cData['type'] = 'demande';
			}

			if (!empty($cData)) {
				$ret = $pms->desarchiver($cData);
			}
		} else {
			$ret	= true;
		}

		return $ret;
	}

	/**
	*@param idResa int, etat int
	*@description : creation d'une nouvelle réservation à partir d'un autre
	*/
	public function createNewResaFrom($idResa = 0, $etat = 1)
	{
		$tableResa = $this->getTableObjet('reservations');
		$tableValDyn = $this->getTableObjet('valeurs_dynamiques');
		$tableChoixLoge = $this->getTableObjet('choix_typelogement');

		$resa = $tableResa->select(array('id' => $idResa))->current();
		if ($resa) {
			$newResaData = get_object_vars($resa);
			$newResaData['id'] = 0;
			$newResaData['etat'] = $etat;
			$newResaData['idLogement'] = null;
			$newResaData['idTypeLogementAttribue'] = null;
			$newResaData['numeroChambre'] = null;
			$newResaData['numDossier'] = null;
			$newResaData['codeSite'] = null;
			$newResaData['numResa'] = null;
			$newResaData['codeSite'] = null;
			$newResaData['idPMS'] = null;
			$newResaData['dateDemandeReservation'] = date('Y-m-d H:i:s');
			$newResaData['archive'] = '0';

			$tableResa->insert($newResaData);
			$idNewResa = $tableResa->lastInsertValue;

			//on copie les valeurs dynamiques
			$valDynRows = $tableValDyn->select(array('idReservation' => $idResa));
			foreach ($valDynRows as $row) {
				$valDynArr = get_object_vars($row);
				$valDynArr['id'] = 0;
				$valDynArr['idReservation'] = $idNewResa;
				$tableValDyn->insert($valDynArr);
			}

			//copie des choix de type de logement
			$choixResult = $tableChoixLoge->select(array('idReservation' => $idResa));
			foreach ($choixResult as $ch) {
				$chArr = get_object_vars($ch);
				$chArr['id'] = 0;
				$chArr['idReservation'] = $idNewResa;
				$tableChoixLoge->insert($chArr);
			}

			//on crée la demande PMS
			$this->ajouterDemandeBredea($idNewResa);
		} else {
			return "Aucune réservation trouvé $idResa";
		}
		return "ok";
	}


	##----------------------------------- PARTIE ONGLETS CATALOGUES ------------------------------##

	## action formawrder depuis LogementController pour recup des catalogues proprietaire
	public function loadLogementsCatalogueTabsAction()
	{
		$idLogement = (int) $this->params()->fromRoute('id', 0);
		$typesCatalogue = $this->getCatalogueTable()->getListeTypesCatalogueParType('proprietaire');
		$ongletsParTypeCatalogue = array();
		foreach ($typesCatalogue as $id => $type) {
			$ongletsParTypeCatalogue[$id] = $this->loadCatalogueTab(0, $id, array('idLogement' => $idLogement, 'from' => 'ficheLogement'));
		}

		return $ongletsParTypeCatalogue;
		exit();
	}

	private function loadCatalogueTab($idResa, $idTypeCatalogue, $params = array())
	{
		$idCatalogue = !empty($params['idCatalogue']) ? $params['idCatalogue'] : null;
		$idDp = !empty($params['idDp']) ? $params['idDp'] : null;
		$idLogement = !empty($params['idLogement']) ? $params['idLogement'] : null;
		$idSuivis = !empty($params['idSuivis']) ? $params['idSuivis'] : null;
		if (!$idResa) {
			$idResa = !empty($params['idResa']) ? $params['idResa'] : null;
		}
		$typeAffichage = !empty($params['typeAffichage']) ? $params['typeAffichage'] : null;
		$from = !empty($params['from']) ? $params['from'] : '';

		$typeChamp = !empty($params['typeChamp']) ? $params['typeChamp'] : '';
		$valeurChamp = !empty($params['valeurChamp']) ? $params['valeurChamp'] : '';

		$idLocataire = 0;
		if ($idResa) {
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if ($resa) {
				$idLocataire = $resa->idLocataire;
			}
		} elseif ($idDp) {
			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
			if ($dp) {
				$idLocataire = $dp->idLocataire;
			}
		}

		//$idDp = null;
		$disabled = !empty($params['disabled']) ? $params['disabled'] : false;
		$typeRetour = !empty($params['typeRetour']) ? $params['typeRetour'] : "";
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=".$idResa." idCatalogue=$idCatalogue");

		$data = array();
		$idsSousLogement = array();
		if($idLogement && $from == 'ficheLogement') {
			$sousLogements = $this->getLogementTable()->getSousLogements($idLogement);
			if(!empty($sousLogements)) {
				$idsSousLogement = array_keys($sousLogements);
				$idsSousLogement[] = $idLogement;
			}
		}

		$funcParams = array('idCatalogue' => $idCatalogue,
						'idTypeCatalogue' => $idTypeCatalogue,
						'idResa' => $idResa,
						'idLocataire' => $idLocataire,
						'idDp' => $idDp,
						'idLogement' => $idLogement,
						'idSuivis' => $idSuivis,
						'typeAffichage' => $typeAffichage,
						'idsSousLogement' => $idsSousLogement);
		$dvs = $this->getCatalogueTable()->getValeursChamps($funcParams);

		/*$cb = $this->getTableObjet('champs_de_base')->select(array('equivalentSql'=>'idUser'))->current();
		$users = array();
		if($cb && $cb->critere){
			$codeTypeArr = json_decode($cb->critere,true);
			if(!empty($codeTypeArr['codeType'])){
				$users = $this->getUserTable()->getUsersListeByCodeType($codeTypeArr['codeType']);
			}
		}*/
		$users =  $this->getUserTable()->getUsersListe();

		$dataListe = array();//valeur par catalogue
		foreach ($dvs as $dv) {
			$val = $dv->dv_valeur;
			$data[$dv->id] = $val;
			$dataListe[$dv->dv_idCatalogue][$dv->id] = $dv->vs_valeur ? $dv->vs_valeur : $dv->dv_valeur;
			if (($dv->equivalentSql == 'idUser' || $dv->sourceListe == 'user') && !empty($users[$val])) {
				$val = $users[$val];
				$dataListe[$dv->dv_idCatalogue][$dv->id] = $val;
			}
		}

		## ajout champ nbrPlacesMax
		if($idCatalogue) {
			$catalogue = $this->getCatalogueTable()->getCatalogue($idCatalogue);
			$champNbrPlaces = $this->getCatalogueTable()->getCatalogueChampsTable()->select(array('equivalentSql' => 'nbrPlacesMax'))->current();
			if($champNbrPlaces) {
				$data[$champNbrPlaces->id] = $catalogue->nbrPlacesMax;
				$dataListe[$idCatalogue][$champNbrPlaces->id] = $catalogue->nbrPlacesMax;
			}
		}
		$data['idCatalogue'] = $idCatalogue;

		$fields = $this->getCatalogueTable()->getChampsTypeCatalogue($idTypeCatalogue, $from);

		$fieldsListe = $this->getCatalogueTable()->getChampsForFicheUsager($idTypeCatalogue);

		//si la liste est vide, on prend le premier champs ajouté
		if (empty($fieldsListe)) {
			$fieldsListe[] = $fields[0];
		}

		if (($typeRetour == "reset" && !$idCatalogue) || $typeRetour == "default") {
			//on vide le formulaire pour un nouveau ajout, ou quand on charge la fiche locataire pour la premier fois
			$data = array();
		}

		// var_dump($fields);die();

		$returnForm = $this->buildCatalogueForm($idResa, $fields, $data, $idTypeCatalogue, $idDp, $disabled);//return array html, validator
		$form = $returnForm['html'];
		$validator = !empty($returnForm['validator']) ? $returnForm['validator'] : array();

		//cas edition de la ligne catalogue du tableau listecatalogue, ou ajout d un nouveau catalogue
		if ($idCatalogue || $typeRetour == "reset") {
			//return array('form'=>$form,'validator'=>$validator);
			return $returnForm;
		}

		$catalogues = $this->getCatalogueTable()->getCataloguesForFicheUsager($funcParams);
		$typeCatalogue = $this->getCatalogueTable()->getTypeCatalogue($idTypeCatalogue);

		if (!$typeChamp && empty($valeurChamp)) {
			if ($idResa) {
				$typeChamp = 'idResa';
				$valeurChamp = $idResa;
			} elseif ($idLogement) {
				$typeChamp = 'idLogement';
				$valeurChamp = $idLogement;
			} elseif ($idDp) {
				$typeChamp = 'idDp';
				$valeurChamp = $idDp;
			} elseif ($idSuivis) {
				$typeChamp = 'idSuivis';
				$valeurChamp = $idSuivis;
			}
		}


		$viewFile = 'reservation/liste/catalogueliste';
		if ($typeAffichage == "affectation") {
			$viewFile = 'reservation/liste/catalogueaffectation';
		}
		//listes des catalogues
		$htmlViewLC = new ViewModel();
		$htmlViewLC->setTerminal(true)
		->setTemplate($viewFile)
		->setVariables(array(
			"fields" => $fieldsListe,
			"data" => $dataListe,
			"catalogues" => $catalogues,
			"idTypeCatalogue" => $idTypeCatalogue,
			"idDp" => $idDp,
			"idResa" => $idResa,
			"idLocataire" => $idLocataire,
			"idLogement" => $idLogement,
			"typeCatalogue" => $typeCatalogue,
			"typeChamp" => $typeChamp,
			"valeurChamp" => is_array($valeurChamp) ? implode('-', $valeurChamp) : $valeurChamp,
			"typeAffichage" => $typeAffichage,
			"from" => $from,
		));
		$htmlLC = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewLC);

		if ($typeRetour == "tableau") {
			return $htmlLC;
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/catalogueTab')
		->setVariables(array(
			"form" => $form,
			"htmlLC" => $htmlLC,
			'idResa' => $idResa,
			"validator" => json_encode($validator, JSON_FORCE_OBJECT),
			"idTypeCatalogue" => $idTypeCatalogue,
			"idDp" => $idDp,
			"idLogement" => $idLogement,
			"typeChamp" => $typeChamp,
			"valeurChamp" => $valeurChamp,
			"from" => $from,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}


	public function buildCatalogueForm($idResa, $champs, $result, $idTypeCatalogue = 0, $idDp = '', $disabled = false)
	{
		$row = 0;
		$html = null;
		$columns = array();
		$tools = new Tools();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = null;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idCatalogue = $result['idCatalogue'] ? $result['idCatalogue'] : -1;
		$validator['locale'] = 'fr_FR';
		$validator['fields'] = array();
		$validator['submitButtons'] = '#catalogue-submit'.$idTypeCatalogue;

		$translator = \zend\Validator\AbstractValidator::getDefaultTranslator();

		$conf = $this->getConfigurationTable()->getConfig(1);
		$typeCatalogue = $this->getCatalogueTable()->getTypeCatalogue($idTypeCatalogue);

		foreach ($champs as $champ) {
			if ($champ->column == 1) {
				$columns[$champ->row][1] = 4 * $champ->tailleColumn;
			} elseif ($champ->column == 2) {
				$columns[$champ->row][2] = 4 * $champ->tailleColumn;
			} elseif ($champ->column == 3) {
				$columns[$champ->row][3] = 4 * $champ->tailleColumn;
			}
		}
		//print_r($columns);exit();

		$idLocataire = "";
		if ($idResa) {
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			if ($resa) {
				$idLocataire = $resa->idLocataire;
			}
		} elseif ($idDp) {
			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();
			if ($dp) {
				$idLocataire = $dp->idLocataire;
			}
		}

		$idsChampsActions = $this->getCatalogueTable()->getChampsLierAuActions();//on y stock tout les champs lier au action pour ne verifier que ceux la

		$champsDoc = array();
		foreach ($champs as $champ) {
			if ($champ->active == 0) {
				continue;
			}

			$extraOption = null;
			$validator['fields'][$champ->equivalentSql]['validators'] = array();
			if ($champ->obligatoire) {
				$extraOption .= ' required ';
			}

			if ($champ->obligatoire) {
				$extraOption .= ' required ';
				$validator['fields'][$champ->equivalentSql]['validators']['notEmpty'] = array();
			}
			

			if (in_array($champ->id, $idsChampsActions)) {
				$extraOption .= ' data-action="1" ';
			}

			if ($row == 0) {
				$row = $champ->row;
			}

			if ($champ->row > $row) {
				$html .= '<div class="clearfix"></div>';
				$row = $champ->row;
			}

			$extraOption .= ' data-idtype="'.$champ->idType.'"';

			$extraOption .= ' data-idchamp="'.$champ->id.'"';

			if ($champ->idType == 7 && trim($conf->txtPlaceholderTextarea) != '') {
				$extraOption .= ' placeholder="'.$conf->txtPlaceholderTextarea.'" ';
			}

			if ($champ->column == 2 && empty($columns[$champ->row][1])) {
				$html .= '<div class="col-md-4"></div>';
				$columns[$champ->row][1] = 4;
			} elseif ($champ->column == 3) {
				if (empty($columns[$champ->row][1])) {
					$html .= '<div class="col-md-4"></div>';
					$columns[$champ->row][1] = 4;
				}
				if (empty($columns[$champ->row][2]) && $columns[$champ->row][1] == 4) {
					$html .= '<div class="col-md-4"></div>';
					$columns[$champ->row][2] = 4;
				}
			}

			$html .= '<div class="col-md-'. 4 * $champ->tailleColumn .'">';

			// type html
			$extraHtml = '';
			$extraHtmlCss = '';
			if ($champ->idType == 10) {
				$extraHtml = $extraOption;
				$extraHtmlCss = " id='".$champ->idCss."' ";
			}

			$classCss = '';
			if ($champ->afficherInfos == 1) {
				$classCss .=  "showinfos ";
			}
			if ($champ->idType == 6) {
				$classCss .=  "showMailTo ";
			}
			$lableOptions = ' data-title="'.$champ->texteInfos.'"';

			if($champ->modifierListe == 1 && ($champ->idType == 3 || $champ->idType == 18)){
				$classCss .=  "modifierListe-cata ";
				$extraOption .= ' data-sourceliste="'.$champ->sourceListe.'"';
			}

			if (!$champ->modifiable || $disabled) {
				if ($champ->idType == 3 || $champ->idType == 18) {
					$extraOption .= ' disabled="disabled" readonly="readonly" ';
				} else {
					$extraOption .= ' readonly="readonly" ';
				}
			}

			// var_dump($champ);die();
			$classFormMonetaire = "";
			if (($champ->afficherUnite == "1" && $champ->idType == 13) || $champ->idType == 12) {
				$classFormMonetaire = "type_13 aligner_left";
			}
			$html .= '<div class="form-group has-feedback '.$classCss.' '.$classFormMonetaire.'">';

			// TEXT
			if ($champ->idType == 1) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" data-id="'.$champ->id.'" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// DATE
			elseif ($champ->idType == 2) {
				$extraMinDate = $extraMaxDate = null;

				$inputVal = '';
				if (array_key_exists($champ->id, $result) && sizeof(explode('-', $result[$champ->id])) == 3) {
					$inputVal = date('d-m-Y', strtotime($result[$champ->id]));
				}

				$extraDate = $this->getTableObjet('champs_catalogue_dateinterval')->select(array('idChamp' => $champ->id))->current();
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" data-id="'.$champ->id.'" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.$inputVal.'" '.$extraOption.' tabindex="-1">';

				$plages = $tools->getPlagesDatesBO($extraDate);
				extract($plages);
				$html .= '<script>
							$("#myCatalogueContent'.$idTypeCatalogue.' #'.$champ->idCss.'").datepicker({
								"format" : "dd-mm-yyyy",
								startDate:\''.$extraMinDate.'\',
								endDate:\''.$extraMaxDate.'\',
								autoclose:true,
								language:\'fr\',
							}).on("changeDate",function(ev) {
								let value = moment(ev.date).format("DD-MM-YYYY");
								$("#myCatalogueContent'.$idTypeCatalogue.' #'.$champ->idCss.'").attr("value", value);

								console.log("hasError", $("#mySuivisContent'.$idTypeSuivis.' #'.$champ->idCss.'").parent().hasClass("has-error"));

								if ($("#myCatalogueContent'.$idTypeCatalogue.' #'.$champ->idCss.'").parent().hasClass("has-error")) {

									$("#myCatalogueContent'.$idTypeCatalogue.' #'.$champ->idCss.'").parent().removeClass("has-error")

									$("#myCatalogueContent'.$idTypeCatalogue.' #'.$champ->idCss.'").parent().find("small").remove();
								}
							});
						</script>';
			}

			// LIST
			elseif ($champ->idType == 3 || $champ->idType == 18) {
				//$select = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$valeurBdd = (array_key_exists($champ->id, $result) && $result[$champ->id]) ? $result[$champ->id] : null;
				$select = $this->getSelectOptions($champ->sourceListe, $champ->options, array('valeurBdd' => $valeurBdd));
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';

				// On cherche si le champ est rélié à un autre champ
				$champsAssociation = $this->getTableObjet('champs_association')
				->select(array('idChamp1' => (int) $champ->id, 'idTypeCatalogue' => (int) $idTypeCatalogue))
				->toArray();
				// On indique que ce champ est lié au champ de la bdd
				$champLinkedTo = "";
				if (count($champsAssociation) > 0) {
					$res = [];
					for ($i = 0; $i < count($champsAssociation); $i++) {
						$res[] = $champsAssociation[$i]['idChamp2'];
					}
					$champLinkedTo = implode("-", array_unique($res));
				}


				$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='NULL'";
				if ($champ->idType == 3 || $champ->idType == 18) {
					$itemsRequiredToActivateSelect2 = "itemsRequiredToActivateSelect2='".
					$champ->itemsRequiredToActivateSelect2."'";
				}

				$isMultiple = $champ->idType == 18 ? "multiple='multiple'" : "";
				$valCatalogueMultiple = "";
				if ($isMultiple !== "" && $idCatalogue > 0) {
				 	$catalogue_values = $this->getTableObjet('catalogue_values')
				 	->select(array('idChamp' => $champ->id, 'idCatalogue' => $idCatalogue))->current();
				 	$valCatalogueMultiple = $catalogue_values->valeur;
				}
				$name = $champ->equivalentSql;
				// if ($champ->idType == 18) {
				// 	$name = $name.'[]';
				// }

				$html .= '<select '.$itemsRequiredToActivateSelect2.' '.$isMultiple.' class="form-control" data-id-select="'.$champ->id.'" id="'.$champ->idCss.'" name="'.$name.'" '.$extraOption.' data-id="'.$champ->id.'" data-linked-to="'.$champLinkedTo.'">';

				// Ajout du champ vide par défaut
				if (count($select) <= intval($champ->itemsRequiredToActivateSelect2)) {
					$html .= '<option data-val-linked="" value="">Veuillez choisir une valeur</option>';
				}

				// $html .= '<option data-val-linked="" value="">Veuillez choisir une valeur</option>';
				foreach ($select as $option) {

					$isMultipleSelected = "";
					if ($isMultiple !== "") {
						if (in_array($option->id, explode(",", $valCatalogueMultiple))) {
							// var_dump($valDemandeMultiple);die();
							$isMultipleSelected = "selected";
						}
					}

					// Liaison entre valeurs de chaque champ
					$val2Linked = [];
					foreach ($champsAssociation as $key => $row) {
						if ($row['idVal1'] == $option->id) {
							$val2Linked[] = $row['idVal2'];
						}
					}

					// Liste des valeurs du champs 2 lesquels sont réliés chaque option du val1
					$val2Linked = count($val2Linked) > 0 ? implode("-", array_unique($val2Linked)) : "";
					$disabledOpt = $option->deleted == 1 ? 'disabled' : '';

					$selected = "";
					if ($champ->idType == 3) {
						$selected = array_key_exists($champ->id, $result) && $result[$champ->id] == $option->id ? 'selected' : '';
					} elseif ($champ->idType == 18) {
						if (array_key_exists($champ->id, $result) && strpos($result[$champ->id], $option->id) !== false) {
							$selected = 'selected';
						}
					}

					$html .= '<option '.$isMultipleSelected.' data-val-linked="'.$val2Linked.'" value="'.$option->id.'" '.$selected.' '.$disabledOpt.' >'.$option->valeur.'</option>';
				}
				$html .= '</select>';
			}

			// DOC
			elseif ($champ->idType == 4) {
				$champsDoc[] = $champ;
				$html .= '<div class="document">';
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$value = array_key_exists($champ->id, $result) ? $result[$champ->id] : '';

				if (!$disabled) {
					$html .= '<input type="file" class="uploadDoc '.$champ->idCss.'" id="'.$champ->idCss.'" name="file_'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';

					$html .= '<br /><span class="fl">'.($translator->translate('l_parcourir')).'</span>';
					$html .= '<div id="progress_'.$champ->equivalentSql.'" class="progress">';
					$html .= '<div class="progress-bar progress-bar-success"></div>';
					$html .= '</div>';
				}
				$html .= '<div id="reponse_'.$champ->equivalentSql.'" class="msg reponse">';
				if ($value && (file_exists(getcwd().'/public/docs/locataires/'.$idLocataire.'/catalogue/'.$value) || file_exists(getcwd().'/public/docs/catalogues/'.$idCatalogue.'/'.$value))) {
					if (!$disabled) {
						$html .= "<span id='delete_".$champ->equivalentSql."' class='link'><i class='fa fa-2x fa-times red'></i></span> ";
					}
					if(file_exists(getcwd().'/public/docs/locataires/'.$idLocataire.'/catalogue/'.$value)){
						$html .= "<a class='pj-link' href='".$this->getBaseUrl().'/docs/locataires/'.$idLocataire.'/catalogue/'.$value."' target='_blank'>";
					}else{
						$html .= "<a class='pj-link' href='".$this->getBaseUrl().'/docs/catalogues/'.$idCatalogue.'/'.$value."' target='_blank'>";
					}
					
					$html .= $value;
					$html .= "</a>";
				} else {
					$value = "";
				}

				$html .= '</div>';
				$html .= '<input type="hidden" name="'.$champ->equivalentSql.'" id="idPjName_'.$champ->equivalentSql.'" value="'.$value.'" />';

				$html .= '<input type="hidden" name="pj-href" id="idPjHref'.$champ->equivalentSql.'" value="'.$this->getBaseUrl().'" />';
				$html .= '</div>';
			}

			// NB
			elseif ($champ->idType == 5) {
				$min = $champ->valeurMin ? 'min="'.$champ->valeurMin.'"' : "";
				$max = $champ->valeurMax ? 'max="'.$champ->valeurMax.'"' : "";
				if ($champ->valeurMin) {
					$validator['fields'][$champ->equivalentSql]['validators']['greaterThan'] = array('value' => $champ->valeurMin);
				}
				if ($champ->valeurMax) {
					$validator['fields'][$champ->equivalentSql]['validators']['lessThan'] = array('value' => $champ->valeurMax);
				}

				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="number" data-id="'.$champ->id.'" class="form-control cata_champ_type_'.$champ->idType.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' '.$min.' '.$max.' >';
			}

			// EMAIL
			elseif ($champ->idType == 6) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="email" data-id="'.$champ->id.'" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			// TEXTAREA
			elseif ($champ->idType == 7) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<textarea class="form-control type_7" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" rows="'.$champ->tailleRow.'" cols="'.$champ->tailleColumn.'" '.$extraOption.' >'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'</textarea>';
			}

			// CHECKBOX
			elseif ($champ->idType == 8) {
				$checked = '';
				if ((array_key_exists($champ->id, $result) && $result[$champ->id]) || (empty($result) && $champ->valeurParDefaut == 1)) {
					$checked = 'checked';
				}
				$html .= '<input id="'.$champ->idCss.'" data-id="'.$champ->id.'" name="'.$champ->equivalentSql.'" type="checkbox" value="1" '.$checked.'  '.$extraOption.' > <label '.$lableOptions.'>'.$champ->libelle.'</label>';
			}

			// RADIO
			elseif ($champ->idType == 9) {
				//$radios = $this->getTableObjet('valeurs_select')->select(array('idSelect'=>$champ->sourceListe,'deleted'=>'0'));
				$valeurBdd = (array_key_exists($champ->id, $result) && $result[$champ->id]) ? $result[$champ->id] : null;
				$radios = $this->getSelectOptions($champ->sourceListe, array(), array('valeurBdd' => $valeurBdd));
				$html .= '<label '.$lableOptions.' style="width:100%;">'.$champ->libelle.'</label>';
				foreach ($radios as $option) {
					$html .= '<div style="width:100%;">';
					$html .= '<input id="'.$option->id.'"  data-id="'.$champ->id.'" name="'.$champ->equivalentSql.'" type="radio" value="'.$option->id.'" '.(array_key_exists($champ->id, $result) && $result[$champ->id] == $option->id ? 'checked' : '').' '.$extraOption.' >'.$option->valeur;
					$html .= '</div>';
				}
			}

			// HTML
			elseif ($champ->idType == 10) {
				$html .= '<div '.$extraHtmlCss.' '.$extraHtml.'><p>'.$champ->description.'</p></div>';
			}

			// PASS
			elseif ($champ->idType == 11) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="password" class="form-control" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" '.$extraOption.' >';
			}

			//Heure
			elseif ($champ->idType == 17) {
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control input-heure" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
				$validator['fields'][$champ->equivalentSql]['validators']['regexp'] = array('regexp' => '^(((([0-1][0-9])|(2[0-3]))((:?[0-5][0-9])|(:?[0-5][0-9]:?[0-5][0-9])))|(24:?00))$');
			} else {
				$classPlg = $champ->idType == 14 ? 'plg-intlTelInput' : '';
				if ($champ->idType == 13) {
					$extraOption .= ' data-formule="'.($champ->formule ? substr($champ->formule, 0, -1) : "").'" readonly="readonly"';
				}
				$html .= '<label '.$lableOptions.' for="'.$champ->idCss.'">'.$champ->libelle.'</label>';
				$html .= '<input type="text" class="form-control '.$classPlg.' cata_champ_type_'.$champ->idType.'" id="'.$champ->idCss.'" name="'.$champ->equivalentSql.'" data-id="'.$champ->id.'" value="'.(array_key_exists($champ->id, $result) ? $result[$champ->id] : '').'" '.$extraOption.' >';
			}

			$html .= '</div>';
			$html .= '</div>';
		}

		// VALIDATION BUTTON
		$html .= '<div class="clearfix"></div>';

		//ajout choix de résidences
		if($gestId && $typeCatalogue->type == 'animation') {
			$html .= '<div class="col-md-4">';
			$html .= '<div class="form-group">';
			$html .= '<label>Résidence de rattachement</label>';
			if($typeCatalogue->type == 'animation') {
				$html .= '<a href="javascript:void(0)" title="Nombre de places" data-type="'.$typeCatalogue->type.'" data-idcatalogue="'.$idCatalogue.'" class="editCatalogueNbrPlaces pull-right " style="display: block;"><i class="fa fa-list"></i></a>';
			}

			$html .= '<select class="form-control id-idResidenceCatalogue" data-idtype="3" name="idResidenceCatalogue[]" id="id-idResidenceCatalogue" itemsRequiredToActivateSelect2="2">';

			$residencesDeCatalogue = array();
			if($idCatalogue) {
				$residencesDeCatalogue = $this->getCatalogueTable()->getResidencesDeCatalogue($idCatalogue,$rattache=true);
			}
			$result = $this->getResidencesTable()->fetchByGest($gestId);
			foreach($result as $row) {
				$selected = '';
				if($idCatalogue && array_key_exists($row->id, $residencesDeCatalogue)) {
					$selected = 'selected="selected"';
				}
				$html .= '<option value="'.$row->id.'" '.$selected.'>'.$row->nom.'</option>';
			}
			$html .= '</select>';
			$html .= '</div>';
			$html .= '</div>';
		}

		$inputHiddenAction = "";
		if (in_array(-2, $idsChampsActions)) {
			$inputHiddenAction = '<input type="hidden" name="idTypeLocataire" class="form-control" value="" data-action="1" />';
		}
		if (in_array(-3, $idsChampsActions)) {
			$inputHiddenAction .= '<input type="hidden" name="payerDG" class="form-control" value="" data-action="1" />';
		}



		$html .= '<div class="col-md-12">
						<input type="hidden" name="idResa" value="'.$idResa.'">
						<input type="hidden" name="idDp" value="'.$idDp.'">
						<input type="hidden" name="idLocataire" value="'.$idLocataire.'" class="catalogue-idLocataire">
						'.$inputHiddenAction.'
				</div>';
		return array('html' => $html, 'validator' => $validator, 'champsDoc' => $champsDoc);
	}


	//rechargement de la liste des lignes catalogues apres validation
	public function loadtablecatalogueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			/*$idResa = $request->getPost('idResa',0);
			$idDp = $request->getPost('idDp',0);
			$idLogement = $request->getPost('idLogement',0);*/
			$typeAffichage = $request->getPost('type', '');
			$idTypeCatalogue = $request->getPost('idTypeCatalogue');
			$typeChamp = $request->getPost('typeChamp', '');
			$valeurChamp = $request->getPost('valeurChamp', '');
			$listeHtml = "";

			if ($typeChamp && $valeurChamp) {
				//$resa = $this->getResaTable()->getResa($idResa);
				$params = array('typeRetour' => 'tableau', 'typeAffichage' => $typeAffichage);
				if ($typeAffichage == 'ficheSuivis') {
					unset($params['typeRetour']);
				}
				if (!is_array($valeurChamp)) {
					$params[$typeChamp] = $valeurChamp;
				} else {
					$params['typeChamp'] = $typeChamp;
					$params['valeurChamp'] = $valeurChamp;
				}
				$listeHtml = $this->loadCatalogueTab(0, $idTypeCatalogue, $params);
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'listeHtml' => $listeHtml,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function loadFormCatalogueExterneAction()
	{
		$mesParams	= $this->getEvent()->getRouteMatch()->getParam('mesParams');
		$htmlOP = '';
		if (is_array($mesParams)) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : mesParams=".json_encode($mesParams));
			$idResa		= $mesParams['idResa'];
			$idCatalogue		= $mesParams['idCatalogue'];
			$idTypeCatalogue = null;
			if($idCatalogue) {
				$catalogue = $this->getCatalogueTable()->getCatalogue($idCatalogue);
				$idTypeCatalogue = $catalogue->idTypeCatalogue;
			}
			$returnForm = $this->loadCatalogueTab($idResa, $idTypeCatalogue, array('typeRetour' => 'reset', 'idCatalogue' => $idCatalogue, 'disabled' => true, 'from' => !empty($mesParams['from']) ? $mesParams['from'] : ''));
			$htmlOP = $returnForm['html'];
		}
		return $htmlOP;
	}

	public function loadFormCatalogueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idCatalogue = $request->getPost('idCatalogue', 0);
			$idTypeCatalogue = $request->getPost('idTypeCatalogue');
			$idResa = $request->getPost('idResa', 0);
			$idDp = $request->getPost('idDp', 0);
			$idSuivis = $request->getPost('idSuivis', 0);
			$valider = $request->getPost('valider', '1');
			$disabled = $valider ? false : true;
			$idsResas = $request->getPost('ids', '');
			$mode = $request->getPost('mode', '');
			$idLogement = $request->getPost('idLogement', 0);
			$from = $request->getPost('from', '');
			$idTypeSuivis = $request->getPost('idTypeSuivis', '');

			$htmlOP = "";

			$catalogue = $this->getCatalogueTable()->getCatalogue($idCatalogue);
			/*if($catalogue && !$idDp) $idDp = $catalogue->idDp;
			if($catalogue && !$idResa) $idResa = $catalogue->idResa;
			if($catalogue && !$idLogement) $idLogement = $catalogue->idLogement;
			if($catalogue && !$idSuivis) $idSuivis = $catalogue->idSuivis;*/

			$returnForm = $this->loadCatalogueTab($idResa, $idTypeCatalogue, array('typeRetour' => 'reset', 'idDp' => $idDp, 'idCatalogue' => $idCatalogue, 'disabled' => $disabled, 'idLogement' => $idLogement));
			$form = $returnForm['html'];
			$champsDoc = !empty($returnForm['champsDoc']) ? $returnForm['champsDoc'] : array();

			$typeChamp = "";
			$valeurChamp = "";
			if ($idResa) {
				$typeChamp = 'idResa';
				$valeurChamp = $idResa;
			} elseif ($idLogement) {
				$typeChamp = 'idLogement';
				$valeurChamp = $idLogement;
			} elseif ($idDp) {
				$typeChamp = 'idDp';
				$valeurChamp = $idDp;
			} elseif ($idSuivis) {
				$typeChamp = 'idSuivis';
				$valeurChamp = $idSuivis;
			}


			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/catalogueform')
			->setVariables(array(
				'form' => $form,
				'idTypeCatalogue' => $idTypeCatalogue,
				'idResa' => $idResa,
				'idCatalogue' => $idCatalogue,
				'etatCourrier' => "",
				'valider' => !$disabled,
				'clear' => !$disabled,
				'idsResas' => !empty($idsResas) ? implode('-', $idsResas) : '',
				'idDp' => $idDp,
				'mode' => $mode,
				'champsDoc' => $champsDoc,
				'idLogement' => $idLogement,
				'isAjout' => (!$disabled && !$idCatalogue) ? 1 : 0,
				'typeChamp' => $typeChamp,
				'valeurChamp' => $valeurChamp,
				'from' => $from,
				'idTypeSuivis' => $idTypeSuivis,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## les logs par ligne, appeler quand on clique sur l affichage des logs dans la list des catalogues, onglet catalogue de la fiche locataire
	public function getlogscatalogueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idCatalogue = $request->getPost('idCatalogue');
			$typeChamp = $request->getPost('typeChamp', '');
			$valeurChamp = $request->getPost('valeurChamp', '');
			$htmlOP = "";
			$rows = array();
			$rows = $this->getCatalogueTable()->getCatalogueHistorique($idCatalogue, $typeChamp, $valeurChamp);

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/cataloguelogs')
			->setVariables(array(
				'rows' => $rows,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## logements de catalogue
	public function getCatalogueLogementsAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idCatalogue = $request->getPost('idCatalogue');
			$htmlOP = "";
			$rows = array();
			$rows = $this->getCatalogueTable()->getLogementsParCatalogue($idCatalogue);

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/cataloguelogements')
			->setVariables(array(
				'rows' => $rows,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
				'success' 	=> true,
				'htmlOP' => $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//appeler lors de l  edition de la catalogue dans l onglet catalogue de la fiche locataire
	public function editcatalogueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idCatalogue = $request->getPost('idCatalogue');
			$idResa = $request->getPost('idResa');
			$idDp = $request->getPost('idDp');
			$idTypeCatalogue = $request->getPost('idTypeCatalogue');
			$formHtml = "";
			$msg = "Erreur chargement";
			if ($idCatalogue && ($idResa || $idDp)) {
				// $resa = $this->getResaTable()->getResa($idResa);
				$returnForm = $this->loadCatalogueTab($idResa, $idTypeCatalogue, array('idCatalogue' => $idCatalogue, 'idDp' => $idDp));
				$formHtml = $returnForm['html'];
				$champsDoc = !empty($returnForm['champsDoc']) ? $returnForm['champsDoc'] : array();
				$msg = "Infos bien chargé";
			}

			$view = new JsonModel(array(
				'success' 	=> true,
				'msg'		=> $msg,
				'formHtml' => $formHtml,
				'idCatalogue' => $idCatalogue,
				'champsDoc' => $champsDoc,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//rest le formulaire des catalogue pour un nouveau ajout
	public function resetcatalogueAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa');
			$idDp = $request->getPost('idDp');
			$idTypeCatalogue = $request->getPost('idTypeCatalogue');
			$formHtml = "";
			$msg = "Erreur chargement, veuillez re essayer.";
			$success = false;
			$msgClass = "danger";
			if ($idResa || $idDp) {
				$return = $this->loadCatalogueTab($idResa, $idTypeCatalogue, array('typeRetour' => 'reset', 'idDp' => $idDp));
				$formHtml = $return['html'];
				$msg = "Veuillez remplir le formulaire et le valider";
				$success = true;
				$msgClass = "success";
			}

			$view = new JsonModel(array(
				'success'  => $success,
				'formHtml' => $formHtml,
				'msgClass' => $msgClass,
				'msg'	   => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	##----------------------------------- FIN PARTIE ONGLETS CATALOGUES ------------------------------##

	## Catalogue table
	public function getCatalogueTable()
	{
		if (!$this->catalogueTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->catalogueTable = new CatalogueTable($adapter);
		}
		return $this->catalogueTable;
	}

	##----------------------------------- CONFIG DES FILTRES LISTES ------------------------------##
	public function loadConfigFiltersAction()
	{
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			$champName = $request->getPost('champName');
			$champType = $request->getPost('champType');
			$idListe = $request->getPost('idListe');
			$mode = $request->getPost('mode');
			$idTypeSuivis = $request->getPost('idTypeSuivis', null);

			$config = $this->getConfigFiltersTable()->getFieldFilter($champName, $idListe, $mode);
			$champ = $this->getChampCatTable()->getChampByName($champName, $mode, $idTypeSuivis);
			//print_r($champ);exit();
			$selectOptions = array();
			if ($champType == 'select') {
				if (($champ && $champ->sourceListe == 'user') || $champName == 'idUser') {
					$selectOptions['loggedUser'] = "Utilisateur connecté";
					if ($champName == 'idUser') {
						$sourceListe = 'user';
					} else {
						$sourceListe = $champ->sourceListe;
					}
					$rows = $this->getSelectOptions($sourceListe);
					foreach ($rows as $row) {
						//$selectOptions[$row->id] = $row->valeur;
					}
				}
			}
			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/config_filters')
			->setVariables(array(
					'champName'	=> $champName,
					'champType'	=> $champType,
					'idListe'	=> $idListe,
					'mode'		=> $mode,
					'unites'	=> $tools->getUnites(),
					'config'	=> $config,
					'champ'		=> $champ,
					'selectOptions' => $selectOptions,
			));

			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'success' => true,
						'htmlOP' => $htmlOP,

			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function validerConfigFiltersAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$champName = $request->getPost('champName', '');
			$champType = $request->getPost('champType', '');
			$idListe = $request->getPost('idListe', '');
			$mode = $request->getPost('mode', '');

			$success = false;
			$msg = '';
			$params = array();
			if ($champName && $champType && $mode) {
				$filters = array();
				if ($champType == 'date') {
					$dateMinNumber = $request->getPost('dateMinNumber', 0);
					$uniteMin = $request->getPost('uniteMin', '');
					$dateMaxNumber = $request->getPost('dateMaxNumber', 0);
					$uniteMax = $request->getPost('uniteMax', '');
					$filters[$champName] = array('dateMinNumber' => $dateMinNumber,
												'uniteMin' => $uniteMin,
												'dateMaxNumber' => $dateMaxNumber,
												'uniteMax' => $uniteMax,
												);
				} elseif ($champType == 'select') {
					$listeValue = $request->getPost('listeValue', array());
					$filters[$champName] = array('listeValue' => $listeValue);
				}
				$params = array('champName' => $champName,
								'champType' => $champType,
								'mode' => $mode,
								'idListe' => $idListe,
								'filters' => $filters,
								);
				$this->getConfigFiltersTable()->saveFilter($params);
				$success = true;
			} else {
				if (!$champName) {
					$msg .= "Erreur : nom du champ vide<br/>";
				}
				if (!$champType) {
					$msg .= "Erreur : type du champ vide<br/>";
				}
				if (!$mode) {
					$msg .= "Erreur : mode de liste vide<br/>";
				}
			}


			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'mode' => $mode,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function supprimerConfigFiltersAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$champName = $request->getPost('champName', '');
			$idListe = $request->getPost('idListe', '');
			$mode = $request->getPost('mode', '');
			$msg = '';
			if ($champName && $idListe && $mode) {
				$this->getConfigFiltersTable()->deleteFilter($champName, $idListe, $mode);
				$success = true;
				$msg = "Suppression de filtre bien fait";
			} else {
				$success = false;
				$msg = "Erreur suppression,";
				if (!$champName) {
					$msg .= " nom de champ inconnu";
				}
				if (!$idListe) {
					$msg .= " idListe inconnu";
				}
				if (!$mode) {
					$msg .= " mode de liste inconnu";
				}
			}

			$view = new JsonModel(array(
						'success' => $success,
						'msg' => $msg,
						'mode' => $mode,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function getConfigFiltersTable()
	{
		if (!$this->configFiltersTable) {
			$this->configFiltersTable = new ConfigFiltersTable($this->getServiceLocator());
		}
		return $this->configFiltersTable;
	}

	public function parametresMailAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$recupererParametresResidences = $request->getPost('recupererParametresResidences');
			$recupererParametresCampagnes = $request->getPost('recupererParametresCampagnes');
			$type = $request->getPost('type', null);
			$idModele = $request->getPost('idModele', null);

			$pametres_mail = $this->getTableObjet('pametres_mail')->select(array('idTypeEmail' => $type))->current();
			if ($idModele && $type == 1) {
				$pametres_mail = $this->getTableObjet('pametres_mail')->select(array('idModele' => $idModele))->current();
			}

			$data = array();
			if ($recupererParametresResidences == '0' || $recupererParametresResidences == '1') {
				$data = array('recupererParametresResidences' => $recupererParametresResidences);
			}
			if ($recupererParametresCampagnes == '0' || $recupererParametresCampagnes == '1') {
				$data = array('recupererParametresCampagnes' => $recupererParametresCampagnes);
			}
			if ($idModele && $type == 1) {
				$data['idModele'] = $idModele;
			}
			if ($pametres_mail) {
				$this->getTableObjet('pametres_mail')->update($data, array('id' => $pametres_mail->id));
			} else {
				$data['idTypeEmail'] = $type;
				$this->getTableObjet('pametres_mail')->insert($data);
			}

			return new JsonModel(array('success' => true));
		}
	}

	## Action login à l'espace résident
	public function loginEspaceResidentAction()
	{
		$idLocataire = $this->params()->fromRoute('id', null);

		$sess = new Container("loc");
		$sess->locFromBO = null;
		$sess->loginBO = null;

		if ($idLocataire) {
			$loc = $this->getLocataireTable()->getLocataire($idLocataire);
			if ($loc) {
				$sess->locFromBO = $loc;
				$sess->loginBO = true;
				return $this->redirect()->toRoute('connexion');
			} else {
				echo "Aucun locataire trouve avec id = $idLocataire";
			}
		} else {
			echo "idLocataire vide!";
		}
		exit();
	}

	public function generataBarCodePdfAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$b64 = $request->getPost('b64');
			$idLocataire = $request->getPost('idLocataire');
			$barcodeText = $request->getPost('barcodeText');

			$b64 = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $b64));

			// On vérifie si le dossier locataire existe sinon on le crée
			$rootDir = getcwd().'/public/docs/locataires/'.$idLocataire;
			if (!is_dir($rootDir)) {
				mkdir($rootDir, 0777);
				chmod($rootDir, 0777);
			}

			// on vérifie si le dossier carte existe sinon on le crée
			$rootDir .= "/carte";
			if (!is_dir($rootDir)) {
				mkdir($rootDir, 0777);
				chmod($rootDir, 0777);
			}

			// $created = file_put_contents(getcwd().'/public/docs/locataires/test.svg', $b64);
			$src = $rootDir.'/'.$barcodeText.'.jpeg';
			$created = file_put_contents($src, $b64);

			if ($created !== false) {
				// on crée le fichier merger
				$dst = imagecreatefromjpeg(getcwd().'/public/prototype-bw.jpeg');
				$src = imagecreatefromjpeg($src);

				// croper l'image
				//find the size of the border.
				$border = 0;
				while (imagecolorat($src, $border, $border) == 0xFFFFFF) {
					$border++;
				}

				//copy the contents, excluding the border
				//This code assumes that the border is the same size on all sides of the image.
				$newimg = imagecreatetruecolor(imagesx($src) - ($border * 2), imagesy($src) - ($border * 2));
				imagecopy($newimg, $src, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg));

				//finally, if you want, overwrite the original image
				imagejpeg($newimg, $rootDir.'/'.$barcodeText.'.jpeg');

				// on met un fond transparent
				// $black = imagecolorallocate($src, 0, 50, 50);
				// imagecolortransparent($src, $black);
				$resp = imagecopymerge($dst, $newimg, 300, 320, 0, 0, 405, 193, 80);
				imagejpeg($dst, $rootDir.'/carte.jpeg');

				// une fois qu'on a l'image on peut imprimer
				// $this->imprimerCarteDp($rootDir.'/merger-'.$barcodeText.'.jpeg', $idLocataire, 'dp');
				$created = true;
			}
			$srcCarte = $rootDir.'/carte.jpeg';
			exec("convert $srcCarte BMP3:".getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp");

			return new JsonModel(array('succeed' => $created, 'srcFile' => "/docs/locataires/".$idLocataire."/carte/123.bmp", 'srcCarte' => $srcCarte, 'idLocataire' => $idLocataire, 'mode' => 'dp'));
		}
	}

	private function printCups($imgb64, $mode, $idLocataire)
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$bitmapF = "";
		if ($mode == 'dp') {
			exec("convert $imgb64 BMP3:".getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp");
			$carteB64 = file_get_contents(getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp");

			$bitmapF = getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp";
			$tableName = "domiciliations";
		} elseif ($mode == 'carteEtudiant') {
			exec("convert $imgb64 BMP3:".getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp");
			$carteB64 = file_get_contents(getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp");

			$bitmapF = getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp";
			$tableName = "locataires";
		}

		$out = null;
		$res = null;
		$resp = exec("lp -d Evolis $bitmapF", $out, $res);
		$whoami = get_current_user();

		// on enregistre dans les logs le retour de l'impression
		$log = new Logs();
		$log->dateOperation = date('Y-m-d H:i:s');
		$log->idGestionnaire = $gestId;
		$log->operation = "Impresssion carte";
		$log->dataBefore = array();
		$log->dataAfter = $out;
		$log->tableName = $tableName;
		// $log->idReservation = $idResa;
		$log->idLocataire = $idLocataire;
		$this->getLogsTable()->saveLogs($log);

		return array('bitmap' => $bitmapF, 'out' => $out, 'res' => $res, 'whoami' => $whoami);
	}


	/*==========================================
	=            Imprimer carte                =
	==========================================*/
	// mode -> dp ou carteEtudiant
	public function imprimerCarteDpAction()
	{
		## Création du socket
		## ~~~~~~~~~~~~~~~~~~
		try {
			$request = $this->getRequest();
			if ($request->isXmlHttpRequest()) {
				$imgb64 = $request->getPost('srcCarte');
				$idLocataire = $request->getPost('idLocataire');
				$mode = $request->getPost('mode');
			}


			$jobs = $this->printCups($imgb64, $mode, $idLocataire);
			return new JsonModel($jobs);

			// echo "Etape 1: Connexion socket:<br>";

			$errorSocket = $key = $installationId = $session = '';

			$continuer = false;

			$socket = socket_create(AF_INET, SOCK_STREAM, 0);
			if ($socket === false) {
				$errorSocket = "<pre> socket_create() a échoué : raison : " . socket_strerror(socket_last_error())."</pre>";
			}

			$domiciliations_config = $this->getTableObjet('domiciliation_config')->select(array('id' => 1))->current();
			## Connexion à l'imprimante
			## ~~~~~~~~~~~~~~~~~~~~~~~~
			$imprimanteIP = $domiciliations_config->ip;
			// $imprimanteIP = '193.248.53.169';
			$imprimantePort = 18000;
			$result = socket_connect($socket, $imprimanteIP, $imprimantePort);
			if ($result === false) {
				$errorSocket = "<pre>socket_connect() a échoué : raison : ($result)" . socket_strerror(socket_last_error($socket))."</pre>";
			} else {
				$continuer = true;
			}
		} catch (Exception $e) {
			echo  "erreur socket: " . $ex->getMessage().'<br>';
			socket_close($socket);
			die();
		}

		if (!$continuer) {
			echo "erreur socket: " . $errorSocket.'<br>';
			die();
		}

		$continuer = false;

		// var_dump($result);die();

		## Requete 0 - Debut de la session
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 2: Requete 0 Debut de la session:<br>";
			$reqD = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"CMD.SendCommand\",
				\"params\":
				{
					\"command\":\"Ss\",
					\"device\":\"Evolis Primacy\", 
					\"timeout\":\"5000\"
				}
			}";

			$swD = socket_write($socket, $reqD, strlen($reqD));
			if ($swD === false) {
				$errorSocket = "<pre>Impossible d'activer la connection tcp : ".socket_strerror(socket_last_error())."</pre>";
			}

			$srD = socket_read($socket, 1024);
			if ($srD === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket srD : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			// var_dump(json_decode($srD));
		} catch (Exception $e) {
			echo "erreur Etape D: ".$ex->getMessage()."<br>";
			socket_close($socket);
			die();
		}

		$retourD = json_decode($srD, true);
		if ($retourD['result'] != 'OK') {
			echo "erreur Etape D: ".$retourD['result']."<br>";
			die();
		}

		## Requete 1 - Initiliser l'impression
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 3: Initiliser l'impression:<br>";

			$req1 = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"PRINT.Begin\",
				\"params\":
				{
					\"device\":\"Evolis Primacy\"
				}
			}";

			$sw1 = socket_write($socket, $req1, strlen($req1));
			if ($sw1 === false) {
				$errorSocket = "<pre>Impossible d'activer la connection tcp : ".socket_strerror(socket_last_error())."</pre>";
			}

			$sr1 = socket_read($socket, 1024);
			if ($sr1 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket sr1 : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			$session = (object) json_decode($sr1);
			$session = $session->result;

			// var_dump($session);
		} catch (Exception $e) {
			echo "Erreur étape 3: ".$ex->getMessage();
			socket_close($socket);
			die();
		}

		if (strlen($session) != 9) {
			echo "erreur Etape 1: ".$retour1['result']."<br>";
			die();
		}

		## Requete 2 - Setter les params de l'imprimante
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 4: Initialiser l'impression: $session<br>";
			$req2 = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"PRINT.Set\",
				\"params\":
				{
					\"data\":\"GRibbonType=RC_YMCKO;Duplex=NONE;FOverlayManagement=FULLVARNISH\",
					\"session\":\"$session\"
				}
			}";

			$sw2 = socket_write($socket, $req2, strlen($req2));
			if ($sw2 === false) {
				$errorSocket = "<pre>Impossible de setter: ".socket_strerror(socket_last_error())."</pre>";
			}

			$sr2 = socket_read($socket, 1024);
			if ($sr2 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket sr2 : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			// var_dump(json_decode($sr2));
		} catch (Exception $e) {
			echo "Erreur PRINT.Set: ".$ex->getMessage()."<br>";
			socket_close($socket);
			die();
		}

		$retour2 = json_decode($sr2, true);
		if ($retour2['result'] != 'OK') {
			echo "erreur Etape 2: ".$retour2['result']."<br>";
			die();
		}

		## Requete 3 - Donner le bitmap - Carte bitmap avec logo uniquement
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		## Récupérer le modèle de carte en base64
		## base64.exe -e nomDuFichierExistant.bmp nomDuNouveauFichierBase64.b64 -> depuis le cmd (base64.exe fournit avec le SDK evelis)
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 5: Donner le bitmap - Carte bitmap avec logo uniquement $session:<br>";

			// var_dump("convert $imgb64 BMP3:123.bmp");
			// die();

			// FAUT INSTALLER => yum install ImageMagick ImageMagick-devel ImageMagick-perl
			// ensuite vérifier => convert --version
			$bitmapF = "";
			if ($mode == 'dp') {
				exec("convert $imgb64 BMP3:".getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp");
				$carteB64 = file_get_contents(getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp");

				$bitmapF = getcwd()."/public/docs/locataires/".$idLocataire."/carte/123.bmp";
			} elseif ($mode == 'carteEtudiant') {
				exec("convert $imgb64 BMP3:".getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp");
				$carteB64 = file_get_contents(getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp");

				$bitmapF = getcwd()."/public/docs/locataires/".$idLocataire."/carte/carteEtudiant.bmp";
			}

			exec("lp -d Evolis $bitmapF");
			return true;

			// $carteB64 = file_get_contents($imgb64);
			$carteB64 = 'base64:'.base64_encode($carteB64);

			// var_dump($carteB64);
			// die();

			$req3 = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"PRINT.SetBitmap\",
				\"params\":
				{
					\"session\":\"$session\",
					\"face\":\"front\",
					\"panel\":\"color\",
					\"data\":\"$carteB64\"
				}
			}";

			// var_dump($req3);die();

			$sw3 = socket_write($socket, $req3, strlen($req3));
			if ($sw3 === false) {
				$errorSocket = "<pre>Impossible de setter le bitmap : ".socket_strerror(socket_last_error())."</pre>";
			}

			$sr3 = socket_read($socket, 1024);
			if ($sr3 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket sr3 : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			// var_dump(json_decode($sw3));
		} catch (Exception $e) {
			echo "Erreur PRINT.SetBitmap: ".$ex->getMessage();
			socket_close($socket);
			die();
		}

		$retour3 = json_decode($sr3, true);
		if ($retour3['result'] != 'OK') {
			echo "erreur Etape 3: ".$retour3['result']."<br>";
			die();
		}

		## Requete 6 - Impression
		## ~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 6: Impression:<br>";

			$req6 = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"PRINT.Print\",
				\"params\":
				{
					\"session\":\"$session\"
				}
			}";

			$sw6 = socket_write($socket, $req6, strlen($req6));
			if ($sw6 === false) {
				$errorSocket = "<pre>Impossible d'imprimer : ".socket_strerror(socket_last_error())."</pre>";
			}

			$sr6 = socket_read($socket, 1024);
			if ($sr6 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket sr6 : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			// var_dump(json_decode($sr6));
		} catch (Exception $e) {
			echo "Erreur PRINT.Print: ".$ex->getMessage();
			socket_close($socket);
			die();
		}

		$retour4 = json_decode($sr6, true);
		if ($retour4['result'] != 'OK') {
			echo "erreur Etape 4: ".$retour4['result']."<br>";
			die();
		} else {
			$this->getTableObjet('cartes')->update(array('carteImprimee' => '1'), array('idLocataire' => $idLocataire, 'actif' => '1'));
		}

		## Requete 8 - Fin de la session
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		try {
			// echo "Etape 7: Fin de la session:<br>";

			$req8 = "{
				\"jsonrpc\":\"2.0\",
				\"id\":\"1\",
				\"method\":\"PRINT.End\",
				\"params\":
				{
					\"device\":\"Evolis Primacy\"
				}
			}";

			$sw8 = socket_write($socket, $req8, strlen($req8));
			if ($sw8 === false) {
				$errorSocket = "<pre>Impossible de fermer la session : ".socket_strerror(socket_last_error()) . "</pre>";
			}

			$sr8 = socket_read($socket, 1024);
			if ($sr8 === false) {
				$errorSocket = "<pre>Impossible de lire à partir du socket sr8 : ".socket_strerror(socket_last_error()) ."</pre>";
			}

			// var_dump(json_decode($sr8));
		} catch (Exception $e) {
			echo "Erreur Fin de la session: " . $ex->getMessage(). "<br>";
			socket_close($socket);
			die();
		}

		$retour5 = json_decode($sr8, true);
		if ($retour5['result'] != 'OK') {
			echo "erreur Etape 5: ".$retour5['result']."<br>";
			die();
		}

		// try {
		// 	$requete = "{
		// 		\"jsonrpc\":\"2.0\",
		// 		\"id\":\"1\",
		// 		\"method\":\"CMD.SendCommand\",
		// 		\"params\":
		// 		{
		// 			\"command\":\"Se\",
		// 			\"device\":\"Evolis Primacy\",
		// 			\"timeout\":\"10000\"
		// 		}
		// 	}";

		// 	$write = socket_write($socket, $requete, strlen($requete));
		// 	if ($write === false) {
		// 		$errorSocket = "<pre>Impossible de setter le code barre : ".socket_strerror(socket_last_error())."</pre>";
		// 	}

		// 	$read = socket_read($socket, 1024);
		// 	if ($read === false)	$errorSocket = "<pre>Impossible de lire à partir du socket read : ".socket_strerror(socket_last_error()) ."</pre>";

		// 	var_dump(json_decode($read));
		// } catch (Exception $e) {
		// 	echo $ex->getMessage();
		// 	socket_close($socket);
		// }

		## Fermeture du socket
		## ~~~~~~~~~~~~~~~~~~~
		socket_close($socket);

		return new JsonModel(array('e' => $session, 'succeed' => 'true'));
	}

	private function loadEDLTab($idResa, $idLocataire, $numeroLogement = "")
	{
		$rows = array();
		//$resa = $this->getTableObjet('reservations')->select(array('id'=>$idResa))->current();
		if ($numeroLogement != "") {
			$logement = $this->getTableObjet('logements')
			->select(array('numero' => $numeroLogement))->current();
			// récupération des edls proprio
			$edlsResult = $this->getTableObjet('edl')
			->select(array('id_logement' => $logement->id, 'proprietaire' => '1'))->toArray();
			foreach ($edlsResult as $edl) {
				$controlEdl = $edl['edl_control'];

				if (trim($controlEdl) == 'acontroler') {
					$controlEdl = 'à contrôler';
				} elseif (trim($controlEdl) == 'controler') {
					$controlEdl = 'contrôlé';
				} elseif (trim($controlEdl) == 'encoursdecontrole') {
					$controlEdl = 'en cours de contrôle';
				}

				$edl['edl_control'] = $controlEdl;
				if(trim($edl['etat']) == 'terminer') {
					$edl['etat'] = 'terminé';
				}

				$rows[$edl['id']] = (object) $edl;
			}
		} else {
			$edlsResult = $this->getEdlTable()->getEdlByLocataire($idLocataire);
			foreach ($edlsResult as $edl) {
				$controlEdl = $edl->edl_control;

				if (trim($controlEdl) == 'acontroler') {
					$controlEdl = 'à contrôler';
				} elseif (trim($controlEdl) == 'controler') {
					$controlEdl = 'contrôlé';
				} elseif (trim($controlEdl) == 'encoursdecontrole') {
					$controlEdl = 'en cours de contrôle';
				}

				$edl->edl_control = $controlEdl;
				if(trim($edl->etat) == 'terminer') {
					$edl->etat = 'terminé';
				}

				$rows[$edl->id] = $edl;
			}
		}

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/edltab')
		->setVariables(array(
			"rows" => $rows,
			"idLocataire" => $idLocataire,
		));


		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	public function editerEnveloppeAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idDp = $request->getPost('idDp');
			$idCarte = $request->getPost('idCarte');
			$b64 = $request->getPost('b64');
			$barcodeText = $request->getPost('barcodeText');

			$b64 = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $b64));

			$dp = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();

			if ($dp) {
				$locataire = $this->getLocatairesTable()->getLocataire($dp->idLocataire);
			} else {
				$carte = $this->getTableObjet('cartes')->select(array('id' => $idCarte))->current();
				$locataire = $this->getLocatairesTable()->getLocataire($carte->idLocataire);
				$dp = $this->getTableObjet('domiciliations')->select(array('id' => $carte->idDp))->current();
			}

			$nomLoc = $locataire->nom;
			$prenomLoc = $locataire->prenom;

			## Check si la campagne DP est de type
			$idMenage = 0;
			$campagneDp = $this->getTableObjet('campagnes')->select(array('utiliserDpPourResa' => '1', 'archive' => '0'))->current();
			if ($campagneDp && $campagneDp->id == $dp->idCampagne) {

				## Aller chercher les résas du locataires
				$resasDp = $this->getTableObjet('reservations')->select(array('idLocataire' => $dp->idLocataire, 'archive' => '0', 'deleted' => '0'))->toArray();

				## Rechercher la résa présente en fonction des dates
				$dateDuJour = date('Y-m-d');
				foreach ($resasDp as $resaDp) {
					if (strtotime($resaDp['dateArrivee']) <= strtotime($dateDuJour) && strtotime($dateDuJour) <= strtotime($resaDp['dateDepart'])) {
						$idMenage = $resaDp['idMenage'];
					} elseif (strtotime($resaDp['dateArrivee']) <= strtotime($dateDuJour) && (is_null($resaDp['dateDepart']) || $resaDp['dateDepart'] == '0000-00-00')) {
						$idMenage = $resaDp['idMenage'];
					}
				}
			}

			$dateEntree = new \DateTime($dp->dateEntree);
			$de = $dateEntree->format('d/m/Y');

			$dateNaissance = new \DateTime($locataire->dateNaissance);
			$dn = $dateNaissance->format('d/m/Y');

			if (strlen($dp->idLocataire) < 6) {
				$add0 = 6 - strlen($dp->idLocataire);
				$ch = "";
				for ($i = 0; $i < $add0; $i++) {
					$ch .= "0";
				}

				$numIdLocataire = $ch . $dp->idLocataire;
			}

			if (strlen($idCarte) < 6) {
				$add0 = 6 - strlen($idCarte);
				$ch = "";
				for ($i = 0; $i < $add0; $i++) {
					$ch .= "0";
				}

				$idCarte = $ch . $idCarte;
			}

			$codeBarreText = $numIdLocataire . "-" . $idCarte;

			// On vérifie si le dossier locataire existe sinon on le crée
			$rootDir = getcwd().'/public/docs/locataires/'.$dp->idLocataire;
			if (!is_dir($rootDir)) {
				mkdir($rootDir, 0777);
				chmod($rootDir, 0777);
			}

			// on vérifie si le dossier carte existe sinon on le crée
			$rootDir .= "/carte";
			if (!is_dir($rootDir)) {
				mkdir($rootDir, 0777);
				chmod($rootDir, 0777);
			}

			$srcEnv = $rootDir.'/'.$codeBarreText.'_enveloppe.jpeg';

			$imgEnv = imagecreatetruecolor(1200, 500);
			$white = imagecolorallocate($imgEnv, 255, 255, 255);
			$black = imagecolorallocate($imgEnv, 0, 0, 0);

			imagealphablending($imgEnv, true);
			imagesavealpha($imgEnv, true);

			imagecolortransparent($imgEnv, $white);
			imagefill($imgEnv, 0, 0, $white);

			// Font Size
			$fsNom = 0;
			$fsPrenom = 0;
			if (strlen($nomLoc) < 18) {
				$fsNom = 70;
			} else {
				$fsNom = 55;
			}
			if (strlen($prenomLoc) < 18) {
				$fsPrenom = 70;
			} else {
				$fsPrenom = 55;
			}

			imagettftext($imgEnv, $fsNom, 0, 25, 90, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $nomLoc);
			imagettftext($imgEnv, $fsPrenom, 0, 25, 210, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $prenomLoc);
			if ($idMenage > 0) {
				imagettftext($imgEnv, 25, 0, 25, 300, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $idMenage);
			}
			imagettftext($imgEnv, 25, 0, 25, 350, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', 'Domicilié le '.$de.'  -  Né le '.$dn);

			imagejpeg($imgEnv, $srcEnv);

			$srcCodeB = $rootDir.'/'.$codeBarreText.'.jpeg';

			if (file_exists($srcCodeB)) {
				$created = file_put_contents($srcCodeB, $b64);

				$srcCodeB = imagecreatefromjpeg($srcCodeB);

				$border = 0;
				while (imagecolorat($srcCodeB, $border, $border) == 0xFFFFFF) {
					$border++;
				}

				//copy the contents, excluding the border
				//This code assumes that the border is the same size on all sides of the image.
				$newimg = imagecreatetruecolor(imagesx($srcCodeB) - ($border * 2), imagesy($srcCodeB) - ($border * 2));
				imagecopy($newimg, $srcCodeB, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg));

				//finally, if you want, overwrite the original image
				imagejpeg($newimg, $rootDir.'/'.$barcodeText.'.jpeg', 100);

				// on met un fond transparent
				// $black = imagecolorallocate($srcCodeB, 0, 50, 50);
				// imagecolortransparent($srcCodeB, $black);
				imagecopymerge($imgEnv, $newimg, 750, 280, 0, 0, 405, 193, 100);
				// imagecopyresampled($imgEnv, $newimg, 20, 350, 0, 0, 400, 200, 405, 193);
				imagejpeg($imgEnv, $rootDir.'/'.$codeBarreText.'_enveloppe.jpeg', 100);

				// une fois qu'on a l'image on peut imprimer
				$created = true;
			} else {
				// $created = file_put_contents(getcwd().'/public/docs/locataires/test.svg', $b64);
				$src = $rootDir.'/'.$codeBarreText.'.jpeg';
				$created = file_put_contents($src, $b64);

				if ($created !== false) {
					// on crée le fichier merger
					$src = imagecreatefromjpeg($src);

					// croper l'image
					//find the size of the border.
					$border = 0;
					while (imagecolorat($src, $border, $border) == 0xFFFFFF) {
						$border++;
					}

					//copy the contents, excluding the border
					//This code assumes that the border is the same size on all sides of the image.
					$newimg = imagecreatetruecolor(imagesx($src) - ($border * 2), imagesy($src) - ($border * 2));
					imagecopy($newimg, $src, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg));

					//finally, if you want, overwrite the original image
					imagejpeg($newimg, $rootDir.'/'.$barcodeText.'.jpeg', 100);

					//copy the contents, excluding the border
					//This code assumes that the border is the same size on all sides of the image.
					$newimg = imagecreatetruecolor(imagesx($src) - ($border * 2), imagesy($src) - ($border * 2));
					imagecopy($newimg, $src, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg));

					//finally, if you want, overwrite the original image
					imagejpeg($newimg, $rootDir.'/'.$barcodeText.'.jpeg', 100);

					// on met un fond transparent
					// $black = imagecolorallocate($src, 0, 50, 50);
					// imagecolortransparent($src, $black);
					imagecopymerge($imgEnv, $newimg, 750, 280, 0, 0, 405, 193, 100);
					// imagecopyresampled($imgEnv, $newimg, 20, 350, 0, 0, 400, 200, 405, 193);
					imagejpeg($imgEnv, $rootDir.'/'.$codeBarreText.'_enveloppe.jpeg', 100);

					// une fois qu'on a l'image on peut imprimer
					$created = true;
				}
			}
			return new JsonModel(array('succeed' => $created, 'file' => '/docs/locataires/'.$dp->idLocataire.'/carte/'.$codeBarreText.'_enveloppe.jpeg'));
		}
	}

	// Récupérer toutes les infos nécessaire pour la création du JsBarcode (indexdp.phtml)
	public function infosDpBarcodeAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idDp = $request->getPost('idDp');

			$domiciliation = $this->getTableObjet('domiciliations')->select(array('id' => $idDp))->current();

			$idLocataire = $domiciliation->idLocataire;

			$carte = $this->getTableObjet('cartes')->select(array('idDp' => $idDp, 'actif' => '1'))->current();

			if ($carte) {
				$idCarte = $carte->id;
			} else {
				$carte_data = array('idDp' => $idDp, 'idLocataire' => $idLocataire, 'dateCreation' => date("Y-m-d H:i:s"), 'actif' => '1', 'carteImprimee' => '0');
				$carteInsert = $this->getTableObjet('cartes')->insert($carte_data);

				$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
				$idCarte = $adapter->getDriver()->getLastGeneratedValue();

				$this->getTableObjet('domiciliations')->update(array('idCarte' => $idCarte), array('id' => $idDp));
			}

			if ($idLocataire && $idCarte) {
				if (strlen($idLocataire) < 6) {
					$add0 = 6 - strlen($idLocataire);
					$ch = "";
					for ($i = 0; $i < $add0; $i++) {
						$ch .= "0";
					}

					$numIdLocataire = $ch . $idLocataire;
				}

				if (strlen($idCarte) < 6) {
					$add0 = 6 - strlen($idCarte);
					$ch = "";
					for ($i = 0; $i < $add0; $i++) {
						$ch .= "0";
					}

					$numIdCarte = $ch . $idCarte;
				}

				$codeBarreText = $numIdLocataire . "-" . $numIdCarte;

				return new JsonModel(array('succeed' => true, 'idDp' => $idDp, 'idLocataire' => $idLocataire, 'idCarte' => $idCarte, 'codeBarreText' => $codeBarreText));
			} else {
				return new JsonModel(array('succeed' => false));
			}
		}
	}



	public function imprimerEnMasseAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$files = $request->getPost('files');
			$debutDuFichier = $request->getPost('debutDuFichier');

			$pdf = new \TCPDF("LANDSCAPE", "px", "B5", true, 'UTF-8', false);

			$pdf->setPrintFooter(false);
			$pdf->setPrintHeader(false);

			if (is_array($files)) {
				foreach ($files as $key => $file) {
					$pdf->AddPage();
					$pdf->setJPEGQuality(100);

					$pdf->Image($file['file'], 100, 70, 0, 0, "JPEG", "", "M", 2, 300, "C", false, false, 0, false, false, fasle);
				}
			} else {
				$pdf->AddPage();
				$pdf->setJPEGQuality(100);

				$pdf->Image($files, 100, 70, 0, 0, "JPEG", "", "M", 2, 300, "C", false, false, 0, false, false, fasle);
			}

			$srcPDF = getcwd().'/public/allenveloppes.pdf';
			chmod($srcPDF, 0777);

			$pdf->Output($srcPDF, "F");

			return new JsonModel(array('succeed' => true, 'pdf' => '/allenveloppes.pdf'));
		}
	}

	public function genererCarteEtudiantAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			// Récupérer le mode d'impression : Evolis ou Papier
			$modePrint = $this->getTableObjet('configuration')->select(array('id' => 1))->current();

			if ($modePrint->modeImpressionCartes == "Evolis") {
				$idsResa = $request->getPost('idsResa');
				$host = $request->getPost('host');
				$allIdsWithQR = $request->getPost('allIdsWithQR');

				// Si c'est pour l'ESSEC (pour QR CODE)
				if (strpos(strtolower($host), "essec") !== false) {
					foreach ($allIdsWithQR as $keyIdsWithQR => $idWithQR) {
						$idLocataire = $idWithQR['idLocataire'];
						$b64qrcode = $idWithQR['b64qrcode'];

						// Stocker infos de la résa du locataire
						$locataire = $this->getLocatairesTable()->getLocataire($idLocataire);
						$prenomLoc = $locataire->prenom;
						$nomLoc = $locataire->nom;
						$codeLocataire = $locataire->codeLocataire;

						// On vérifie si le dossier locataire existe sinon on le crée
						$rootDir = getcwd().'/public/docs/locataires/'.$idLocataire;
						if (!is_dir($rootDir)) {
							mkdir(getcwd()."/public/docs/locataires/".$idLocataire, 0755, true);
							chown(getcwd().'/public/docs/locataires/'.$idLocataire, 'apache');
							chgrp(getcwd().'/public/docs/locataires/'.$idLocataire, 'apache');
						} else {
							chown(getcwd().'/public/docs/locataires/'.$idLocataire, 'apache');
							chgrp(getcwd().'/public/docs/locataires/'.$idLocataire, 'apache');
						}

						// on vérifie si le dossier carte existe sinon on le crée
						$rootDir .= "/carte";
						if (!is_dir($rootDir)) {
							mkdir($rootDir, 0755, true);
							chown($rootDir, 'apache');
							chgrp($rootDir, 'apache');
						}

						// Création de l'image des infos du locataire
						$srcEnv = $rootDir.'/carteUsager_'.$idLocataire.'.jpeg';

						$imgEnv = imagecreatetruecolor(1016, 648);
						$white = imagecolorallocate($imgEnv, 255, 255, 255);
						$black = imagecolorallocate($imgEnv, 0, 0, 0);

						imagealphablending($imgEnv, true);
						imagesavealpha($imgEnv, true);

						imagecolortransparent($imgEnv, $white);
						imagefill($imgEnv, 0, 0, $white);

						$srcQrCode = $rootDir.'/qrcode.jpeg';
						$b64 = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $b64qrcode));
						$created = file_put_contents($srcQrCode, $b64);
						if ($created !== false) {
							$imgQrCode = imagecreatefromjpeg($srcQrCode);
							imagecopymerge($imgEnv, $imgQrCode, 80, 230, 0, 0, 300, 300, 100);
							imagejpeg($imgEnv, $srcEnv, 100);
							$created = true;
						}

						$fontSize = 25;
						imagettftext($imgEnv, $fontSize, 0, 450, 320, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $nomLoc);
						imagettftext($imgEnv, $fontSize, 0, 450, 370, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $prenomLoc);
						imagettftext($imgEnv, $fontSize, 0, 450, 530, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $codeLocataire);

						imagejpeg($imgEnv, $srcEnv, 100);

						$this->printCups($srcEnv, 'carteEtudiant', $idLocataire);
					}

					return new JsonModel(array('succeed' => 'true'));
					// Sans QR CODE
				} else {
					$files = array();
					foreach ($idsResa as $key => $idResa) {
						// Stocker infos de la résa du locataire
						$resa = $this->getResaTable()->getResa($idResa);
						$locataire = $this->getLocatairesTable()->getLocataire($resa->idLocataire);

						$prenomLoc = $locataire->prenom;
						$nomLoc = $locataire->nom;
						$codeLocataire = $locataire->codeLocataire;

						// On vérifie si le dossier locataire existe sinon on le crée
						$rootDir = getcwd().'/public/docs/locataires/'.$resa->idLocataire;
						if (!is_dir($rootDir)) {
							mkdir(getcwd()."/public/docs/locataires/".$resa->idLocataire, 0755, true);
							chown(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
							chgrp(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
						} else {
							chown(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
							chgrp(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
						}

						$dateN = new \DateTime($locataire->dateNaissance);
						$dateNaissance = $dateN->format('d/m/Y');

						$dateA = new \DateTime($resa->dateArrivee);
						$dateArriveeResa = $dateA->format('d/m/Y');
						$dateD = new \DateTime($resa->dateDepart);
						$dateDepartResa = $dateD->format('d/m/Y');

						// Récupérer les champs formulaires inCarteUsager = 1
						$champInCarte = $this->getTableObjet('champs_formulaires')->select(array('inCarteUsager' => '1'))->current();
						// Si le champ est standard on prend la valeur de la table locataire
						if ($champInCarte->nature == "standard") {
							$photo = $locataire->photo;
						} else {
							$valDyn = $this->getTableObjet('valeurs_dynamiques')->select(array('idChamp' => $champInCarte->id, 'idReservation' => $idResa))->current();
							$photo = $valDyn->valeur;
						}

						$dateCarte = "2024 / 2025";

						// Récupérer et redimensionner la photo d'identité
						$srcPhotoId = $rootDir ."/". $photo;
						if (file_exists($srcPhotoId)) {
							$this->resize_img($srcPhotoId, $srcPhotoId, 532, 414);
							$photoId = imagecreatefromjpeg($srcPhotoId);
						}

						// on vérifie si le dossier carte existe sinon on le crée
						$rootDir .= "/carte";
						if (!is_dir($rootDir)) {
							mkdir($rootDir, 0755, true);
							chown($rootDir, 'apache');
							chgrp($rootDir, 'apache');
						}

						// Création de l'image des infos du locataire
						$srcEnv = $rootDir.'/carteUsager_'.$resa->idLocataire.'.jpeg';

						$imgEnv = imagecreatetruecolor(1016, 648);
						$white = imagecolorallocate($imgEnv, 255, 255, 255);
						$black = imagecolorallocate($imgEnv, 0, 0, 0);

						imagealphablending($imgEnv, true);
						imagesavealpha($imgEnv, true);

						imagecolortransparent($imgEnv, $white);
						imagefill($imgEnv, 0, 0, $white);

						$fontSize = 30;
						imagettftext($imgEnv, $fontSize, 0, 645, 350, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $dateCarte);
						imagettftext($imgEnv, $fontSize, 0, 485, 500, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $nomLoc);
						imagettftext($imgEnv, $fontSize, 0, 485, 550, $black, getcwd().'/public/fonts/poppins/Poppins-Black.ttf', $prenomLoc);

						imagejpeg($imgEnv, $srcEnv, 100);

						// $sizePhotoId = list($width, $height) = getimagesize($srcPhotoId);
						$data = getimagesize($srcPhotoId);
						$width = $data[0];
						$height = $data[1];

						// Coller l'image des infos sur l'image du modèle de carte
						$carteModele = imagecreatefromjpeg(getcwd().'/public/carte_etudiant.jpeg');
						imagecopymerge($carteModele, $photoId, 50, 50, 0, 0, $width, $height, 100);

						imagecopymerge($carteModele, $imgEnv, 0, 0, 0, 0, 1016, 648, 100);
						imagejpeg($carteModele, $srcEnv, 100);

						$files[] = "/docs/locataires/".$resa->idLocataire."/carte/carteUsager_".$resa->idLocataire.".jpeg";
						// $this->printCups($srcEnv, 'carteEtudiant', $resa->idLocataire);
					}
					return new JsonModel(array('succeed' => 'true', 'files' => $files));
				}
			} elseif ($modePrint->modeImpressionCartes == "Papier") {
				$idResa = $request->getPost('idResa');
				$emplacement = $request->getPost('emplacement');

				// Stocker infos de la résa du locataire
				$resa = $this->getResaTable()->getResa($idResa);
				$locataire = $this->getLocatairesTable()->getLocataire($resa->idLocataire);

				// $file = getcwd()."/public/docs/locataires/".$resa->idLocataire."/carte/carteUsager.jpeg";
				// if(!file_exists($file)){

				$prenomLoc = $locataire->prenom;
				$nomLoc = $locataire->nom;

				$dateN = new \DateTime($locataire->dateNaissance);
				$dateNaissance = $dateN->format('d/m/Y');

				// $date = new \DateTime('NOW');
				// $dateCarte = $date->format('Y');

				$dateA = new \DateTime($resa->dateArrivee);
				$dateArriveeResa = $dateA->format('d/m/Y');
				$dateD = new \DateTime($resa->dateDepart);
				$dateDepartResa = $dateD->format('d/m/Y');

				// On vérifie si le dossier locataire existe sinon on le crée
				$rootDir = getcwd().'/public/docs/locataires/'.$resa->idLocataire;
				if (!is_dir($rootDir)) {
					mkdir(getcwd()."/public/docs/locataires/".$resa->idLocataire, 0755, true);
					chown(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
					chgrp(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
				} else {
					chown(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
					chgrp(getcwd().'/public/docs/locataires/'.$resa->idLocataire, 'apache');
				}

				// Récupérer les champs formulaires inCarteUsager = 1
				$champInCarte = $this->getTableObjet('champs_formulaires')->select(array('inCarteUsager' => '1'))->current();
				// Si le champ est standard on prend la valeur de la table locataire
				if ($champInCarte->nature == "standard") {
					$photo = $locataire->photo;
				} else {
					$valDyn = $this->getTableObjet('valeurs_dynamiques')->select(array('idChamp' => $champInCarte->id, 'idReservation' => $idResa))->current();
					$photo = $valDyn->valeur;
				}

				$dateCarte = "24 / 2025";

				// Récupérer et redimensionner la photo d'identité
				$srcPhotoId = $rootDir ."/". $photo;
				if (file_exists($srcPhotoId)) {
					$this->resize_img($srcPhotoId, $srcPhotoId, 385, 285);
					$photoId = imagecreatefromjpeg($srcPhotoId);
				}

				// on vérifie si le dossier carte existe sinon on le crée
				$rootDir .= "/carte";
				if (!is_dir($rootDir)) {
					mkdir($rootDir, 0755, true);
					chown($rootDir, 'apache');
					chgrp($rootDir, 'apache');
				}

				// Création de l'image des infos du locataire
				$srvCarte = $rootDir.'/carteUsager.jpeg';

				$imgEnv = imagecreatetruecolor(1016, 648);
				$white = imagecolorallocate($imgEnv, 255, 255, 255);
				$red = imagecolorallocate($imgEnv, 255, 0, 0);
				$black = imagecolorallocate($imgEnv, 0, 0, 0);

				imagealphablending($imgEnv, true);
				imagesavealpha($imgEnv, true);

				imagecolortransparent($imgEnv, $white);
				imagefill($imgEnv, 0, 0, $white);

				$fontSize = 28;

				imagettftext($imgEnv, $fontSize, 0, 815, 125, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $dateCarte);

				imagettftext($imgEnv, $fontSize, 0, 510, 210, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $prenomLoc." ".$nomLoc);

				imagettftext($imgEnv, $fontSize, 0, 610, 290, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $dateNaissance);

				imagettftext($imgEnv, $fontSize, 0, 520, 365, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', 'MEC');

				imagettftext($imgEnv, $fontSize, 0, 420, 440, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $dateArriveeResa);

				imagettftext($imgEnv, $fontSize, 0, 740, 440, $black, getcwd().'/public/fonts/poppins/Poppins-Regular.ttf', $dateDepartResa);

				// $sizePhotoId = list($width, $height) = getimagesize($srcPhotoId);
				$data = getimagesize($srcPhotoId);
				$width = $data[0];
				$height = $data[1];

				// Coller l'image des infos sur l'image du modèle de carte
				imagecopymerge($imgEnv, $photoId, 40, 160, 0, 0, $width, $height, 100);

				$imgSignature = imagecreatefromjpeg(getcwd().'/public/Signature_sanstampon.jpeg');
				imagecopymerge($imgEnv, $imgSignature, 725, 510, 0, 0, 266, 142, 100);

				imagejpeg($imgEnv, $srvCarte, 100);

				// Créer une image format A4
				$imgA4 = imagecreatetruecolor(2480, 3508);
				$white = imagecolorallocate($imgA4, 255, 255, 255);
				$black = imagecolorallocate($imgA4, 0, 0, 0);
				imagealphablending($imgA4, true);
				imagesavealpha($imgA4, true);
				imagecolortransparent($imgA4, $white);
				imagefill($imgA4, 0, 0, $white);

				$srcEnv = $rootDir;
				// $srcEnv = $rootDir.'/carteUsager.jpeg';
				if ($emplacement == "1") {
					imagecopymerge($imgA4, $imgEnv, 225, 200, 0, 0, 1016, 648, 100);
					$srcEnv .= "/carteUsager_1.jpeg";
				} elseif ($emplacement == "2") {
					imagecopymerge($imgA4, $imgEnv, 225, 1432, 0, 0, 1016, 648, 100);
					$srcEnv .= "/carteUsager_2.jpeg";
				} elseif ($emplacement == "3") {
					imagecopymerge($imgA4, $imgEnv, 225, 2668, 0, 0, 1016, 648, 100);
					$srcEnv .= "/carteUsager_3.jpeg";
				}

				$carteModele = imagecreatefromjpeg(getcwd().'/public/carte_etudiant.jpeg');
				imagecopymerge($carteModele, $photoId, 50, 50, 0, 0, $width, $height, 100);

				// imagecopymerge($imgA4, $imgEnv, 210, 210, 0, 0, 1016, 648, 100); // 1
				// imagecopymerge($imgA4, $imgEnv, 210, 1430, 0, 0, 1016, 648, 100); // 2
				// imagecopymerge($imgA4, $imgEnv, 210, 2650, 0, 0, 1016, 648, 100); // 3

				imagejpeg($imgA4, $srcEnv, 100);
			}
			// }
			// else {
			// 	$srcEnv = $file;
			// }

			$srcFile = "/docs/locataires/".$resa->idLocataire."/carte";
			// $srcFile = "/docs/locataires/".$resa->idLocataire."/carte/carteUsager.jpeg";

			if ($emplacement == "1") {
				$srcFile .= "/carteUsager_1.jpeg";
			} elseif ($emplacement == "2") {
				$srcFile .= "/carteUsager_2.jpeg";
			} elseif ($emplacement == "3") {
				$srcFile .= "/carteUsager_3.jpeg";
			} else {
				$srcFile .= "/carteUsager.jpeg";
			}
			// $this->imprimerCarteDp($srcEnv, $resa->idLocataire, 'carteEtudiant');
			return new JsonModel(array('succeed' => 'true', 'file' => $srcFile, 'srcCarte' => $srcEnv, 'idLocataire' => $resa->idLocataire, 'mode' => 'carteEtudiant', 'modePrint' => $modePrint->modeImpressionCartes));
		}
	}

	public function imprimerEnMasseCarteEtudiantAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('idsResa');
			foreach ($idsResa as $key => $idResa) {
				$resa = $this->getResaTable()->getResa($idResa);
				$src = getcwd().'/public/docs/locataires/'.$resa->idLocataire.'/carte/carteUsager_'.$resa->idLocataire.'.jpeg';
				$this->printCups($src, 'carteEtudiant', $resa->idLocataire);
			}
			return new JsonModel(array('succeed' => 'true'));
		}
	}

	public function printCartePapierAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$emplacement = $request->getPost('emplacement');

			if (!is_dir(getcwd()."/public/docs/cartesEtiquettes")) {
				mkdir(getcwd()."/public/docs/cartesEtiquettes");
			}
			$finalPath = getcwd().'/public/docs/cartesEtiquettes/cartesEtiquettes.jpg';

			$imgA4 = imagecreatetruecolor(2480, 3508);
			$white = imagecolorallocate($imgA4, 255, 255, 255);
			imagealphablending($imgA4, true);
			imagesavealpha($imgA4, true);
			imagecolortransparent($imgA4, $white);
			imagefill($imgA4, 0, 0, $white);

			foreach ($ids as $key => $id) {
				$cartePath = getcwd().'/public/docs/locataires/'.$id.'/carte/carte.jpeg';
				$this->resize_img($cartePath, $cartePath, 574, 900);
				$carteImg = imagecreatefromjpeg($cartePath);

				$data = getimagesize($cartePath);
				$width = $data[0];
				$height = $data[1];

				$xg = 200;
				$xd = 1366;
				$yg = 124;
				$yd = 124;

				$position = $key + $emplacement;

				if ($position == 1) {
					imagecopymerge($imgA4, $carteImg, $xg, $yg, 0, 0, $width, $height, 100);
				} elseif ($position == 6) {
					imagecopymerge($imgA4, $carteImg, $xd, $yd, 0, 0, $width, $height, 100);
				} elseif ($position <= 5) {
					$yg += 674 * ($position - 1);
					imagecopymerge($imgA4, $carteImg, $xg, $yg, 0, 0, $width, $height, 100);
				} elseif ($position > 6) {
					$yd += 674 * ($position - 6);
					imagecopymerge($imgA4, $carteImg, $xd, $yd, 0, 0, $width, $height, 100);
				}
			}
			imagejpeg($imgA4, $finalPath, 100);

			$nbRandom = rand();
			return new JsonModel(array('succeed' => 'true', 'file' => '/docs/cartesEtiquettes/cartesEtiquettes.jpg?'.$nbRandom));
		}
	}

	/**
	 * Fonction qui permet de redimensionner une image en conservant les proportions
	 * @param  string  $image_path Chemin de l'image
	 * @param  string  $image_dest Chemin de destination de l'image redimentionnée (si vide remplace l'image envoyée)
	 * @param  integer $max_size   Taille maximale en pixels
	 * @param  integer $qualite    Qualité de l'image entre 0 et 100
	 * @param  string  $type       'auto' => prend le coté le plus grand
	 *                             'width' => prend la largeur en référence
	 *                             'height' => prend la hauteur en référence
	 * @param  boleen  $upload 	   true si c'est une image uploadée, false si c'est le chemin d'une image déjà sur le serveur
	 * @return string              'success' => redimentionnement effectué avec succès
	 *                             'wrong_path' => le chemin du fichier est incorrect
	 *                             'no_img' => le fichier n'est pas une image
	 *                             'resize_error' => le redimensionnement a échoué
	 */
	public function resize_img($image_path, $image_dest, $max_height, $max_width)
	{

		// Vérification que le fichier existe
		if (!file_exists($image_path)) {
			return 'wrong_path';
		}

		if ($image_dest == "") {
			$image_dest = $image_path;
		}

		// Extensions et mimes autorisés
		$extensions = array('jpg', 'jpeg', 'png', 'gif');
		$mimes = array('image/jpeg', 'image/gif', 'image/png');

		// Récupération de l'extension de l'image
		$tab_ext = explode('.', $image_path);
		$extension  = strtolower($tab_ext[count($tab_ext) - 1]);

		// Récupération des informations de l'image
		$image_data = getimagesize($image_path);

		// Test si l'extension est autorisée
		if (in_array($extension, $extensions) && in_array($image_data['mime'], $mimes)) {

			// On stocke les dimensions dans des variables
			$img_width = $image_data[0];
			$img_height = $image_data[1];

			// Calcul des nouvelles dimensions à partir de la hauteur
			if ($max_height > $img_height) {
				$new_height = $max_height;
				$new_width = $max_width;
			} else {
				$new_height = $max_height;
				$reduction = (($new_height * 100) / $img_height);
				$new_width = round((($img_width * $reduction) / 100), 0);
				if ($new_width > $max_width) {
					$new_width = $max_width;
					$reduction = (($new_width * 100) / $img_width);
					$new_height = round((($img_height * $reduction) / 100), 0);
				}
			}
		}
		// Création de la ressource pour la nouvelle image
		$dest = imagecreatetruecolor($new_width, $new_height);

		// En fonction de l'extension on prépare l'iamge
		switch ($extension) {
			case 'jpg':
				// Certaines images avec l'extension .jpg peuvent poser des problèmes si l'image de base est en .png mais juste renomé en .jpg
				// conversion avec imagemagick
				// Why am I getting the error: “Not a JPEG file: starts with 0x89 0x50”
				// https://stackoverflow.com/questions/11310220/why-am-i-getting-the-error-not-a-jpeg-file-starts-with-0x89-0x50

				$imgE = explode(".", $image_path)[0];
				exec("convert $image_path $imgE.jpg");
				// no break
			case 'jpeg':

				$imgE = explode(".", $image_path)[0];
				exec("convert $image_path $imgE.jpeg");

				$src = imagecreatefromjpeg($image_path); // Pour les jpg et jpeg
				break;
			case 'png':
				$src = imagecreatefrompng($image_path); // Pour les png
				break;
			case 'gif':
				$src = imagecreatefromgif($image_path); // Pour les gif
				break;
		}

		// Création de l'image redimentionnée
		if (imagecopyresampled($dest, $src, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height)) {
			// On remplace l'image en fonction de l'extension
			switch ($extension) {
				case 'jpg':
				case 'jpeg':
					imagejpeg($dest, $image_dest, 100); // Pour les jpg et jpeg
					break;

				case 'png':
					imagepng($dest, $image_dest, 100); // Pour les png
					break;

				case 'gif':
					imagegif($dest, $image_dest, 100); // Pour les gif
					break;
			}
			return 'success';
		} else {
			return 'resize_error';
		}
	}

	public function getSuivisTable()
	{
		if (!$this->SuivisTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$sm = $this->getServiceLocator();
			$this->SuivisTable = $sm->get('Reservation\Model\MultisuivisTable');
			$this->SuivisTable->setAdapter($adapter);
		}
		return $this->SuivisTable;
	}

	public function trombinoscopeAction()
	{
		$request = $this->getRequest();
		$tools = new Tools();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids');
			$columns = $request->getPost('columns'); // Colonnes de la liste dans le dÃ©sordre
			$ordreCol = $request->getPost('ordreCol'); // Ordre des colonnes de la liste
			$allRows = $request->getPost('allRows'); // Lignes de la liste avec valeurs
		}

		$personnes = [];
		foreach ($allRows as $keyRow => $row) {
			$personne = [];
			$personne['hasColoc'] = "non";
			$occupant = [];
			$i = 0;
			foreach ($ordreCol as $keyCol => $oCol) {
				// Enlever la 1ere colonne (correspond au select) et la derniÃ¨re colonne (correspond au Action)
				if ($keyCol == 0 || ++$keyCol === count($columns)) {
					continue;
				}

				$col = $columns[$oCol]['data'];

				// A chaque champ "photo" trouvÃ©, crÃ©er une nouvelle personne si une valeur existe
				if (strpos(strtolower($col), "photo") !== false) {
					$i++;
					if ($i > 1) {
						if ($row["$col"] != "") {
							$occupant["photo"] = 'docs/locataires/'.$row['idLocataire'].'/'.$row["$col"];
						} else {
							$occupant["photo"] = '';
						}
					} else {
						if ($row["$col"] != "") {
							$personne["$col"] = 'docs/locataires/'.$row['idLocataire'].'/'.$row["$col"];
						} else {
							$personne["$col"] = '';
						}
					}
				} else {
					if ($i > 1) {
						if ($row["$col"] == "") {
							$occupant["$col"] = "-";
						} else {
							$occupant["$col"] = $row["$col"];
							$personne['hasColoc'] = "oui";
						}
					} else {
						$personne["$col"] = $row["$col"] == "" ? "-" : $row["$col"];
					}
				}
			}

			// Aller chercher le idBatiment pour le tri
			$resa = $this->getTableObjet('reservations')->select(array('id' => $row['idReservation']))->current();
			$logement = $this->getTableObjet('logements')->select(array('id' => $resa->idLogement))->current();
			$personne['idBatiment'] = $logement->idBatiment;
			$personne['coloc'] = (object) $occupant;
			$personnes[] = (object) $personne;
		}

		// Tri par rÃ©sidences et par batiments
		$residences = $this->getTableObjet('residences')->select()->toArray();
		$batiments = $this->getTableObjet('batiments')->select()->toArray();

		foreach ($residences as $keyRes => $residence) {
			foreach ($batiments as $keyBat => $bat) {
				if ($residence['id'] == $bat['idResidence']) {
					foreach ($personnes as $keyPers => $pers) {
						if ($pers->idBatiment == $bat['id']) {
							$personnesTriees[$residence['nom']][$bat['nom']][] = $pers;
						}
					}
				}
			}
		}

		// CrÃ©ation du pdf pour l'impression
		$pdf = new Mytcpdf("L", "px", "A4", true, 'UTF-8', false, false);

		$pdf->setPrintHeader(false);
		$pdf->setPrintFooter(true);

		$pdf->SetTopMargin(0);
		$pdf->SetFooterMargin(0);

		$pdf->SetAutoPageBreak(true, 30);

		$pdf->AddPage();

		$htmlBody = '';

		$last_res = end(array_keys($personnesTriees));
		foreach ($personnesTriees as $keyR => $res) {
			if ($keyR == $last_res) {
				$htmlBody .= '<div>';
			} else {
				$htmlBody .= '<div style="page-break-after: always;">';
			}

			$last_key = end(array_keys($res));
			foreach ($res as $keyB => $bat) {
				if ($keyB == $last_key) {
					$htmlBody .= '<div>';
				} else {
					$htmlBody .= '<div style="page-break-after: always;">';
				}

				$table = '';
				$table .= '<table cellpadding="2px" width="100%">';
				$table .= '<thead>';
				$table .= '<tr>
					<td style="text-align: center; font-weight: bold;">'.$keyR.' - '.$keyB.'</td>
				</tr>';
				$table .= '</thead>';

				$table .= '<tbody width="100%">';

				$x = 0;

				$table .= '<tr>';

				foreach ($bat as $keyP => $usager) {
					if ($x == 7 || ($usager->hasColoc == "oui" && $x == 6)) {
						$table .= '</tr>';
						$table .= '<tr style="page-break-inside: avoid;">';
						$x = 0;
					}
					$x++;

					if ($usager->hasColoc == "oui") {
						$table .= '<td style="line-height: 16px; width:13%; text-align:center; border-left: 1px thin black; border-top: 1px thin black; border-bottom: 1px thin black;">';
					} else {
						$table .= '<td style="line-height: 16px; width:13%; text-align:center; border: 1px thin black;">';
					}

					if ($usager->photo != "" && file_exists(getcwd().'/public/'.$usager->photo)) {
						$table .= '<img src="/'.$usager->photo.'" width="67" height="85"/>';
					} else {
						$table .= '<img src="/placeholder-img.jpeg" width="67" height="85"/>';
					}

					$table .= '<p style="font-size:9px;text-align:center">';

					$champsListe = '';
					foreach ($usager as $keyChamp => $champ) {
						if ((strpos(strtolower($keyChamp), "photo") === false) && (strpos($keyChamp, "idBatiment") === false) && (strpos($keyChamp, "coloc") === false) && (strpos($keyChamp, "hasColoc") === false)) {
							if (strpos($keyChamp, "date") !== false && $tools->isValideDate($champ)) {
								$champsListe .= '<br>'.date("d-m-Y", strtotime($champ));
							} else {
								$champsListe .= '<br>'.$champ;
							}
						}
					}

					$table .= $champsListe.'</p>';

					$table .= '</td>';

					if ($usager->hasColoc == "oui") {
						$table .= '<td style="line-height: 16px; width:13%; text-align:center; border-right: 1px thin black; border-top: 1px thin black; border-bottom: 1px thin black;">';

						if ($usager->coloc->photo != "" && file_exists(getcwd().'/public/'.$usager->coloc->photo)) {
							$table .= '<img src="/'.$usager->coloc->photo.'" width="67" height="85"/>';
						} else {
							$table .= '<img src="/placeholder-img.jpeg" width="67" height="85"/>';
						}

						$table .= '<p style="font-size:9px;text-align:center">';

						$champsListe = '';
						foreach ($usager->coloc as $keyChamp => $champ) {
							if ((strpos(strtolower($keyChamp), "photo") === false) && (strpos($keyChamp, "idBatiment") === false) && (strpos($keyChamp, "coloc") === false)) {
								if (strpos($keyChamp, "date") !== false && $tools->isValideDate($champ)) {
									$champsListe .= '<br>'.date("d-m-Y", strtotime($champ));
								} else {
									$champsListe .= '<br>'.$champ;
								}
							}
						}

						$table .= $champsListe.'</p>';

						$table .= '</td>';

						$x++;
					}
				}

				$table .= '</tr>';

				$table .= '</tbody>';
				$table .= '</table>';
				$htmlBody .= $table;
				$htmlBody .= '</div>';
			}
			$htmlBody .= '</div>';
		}

		$pdf->writeHTMLCell(880, '', $pdf->getX(), $pdf->getY(), '<div>'.$htmlBody.'</div>', 0, 0, 0, true, '', true);

		$srcPDF = getcwd().'/public/docs/pdfTrombi.pdf';
		// chmod($srcPDF, 0777);

		$pdf->Output($srcPDF, "F");

		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/trombinoscope')
		->setVariables(array(
			'personnesTriees' => $personnesTriees,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		file_put_contents(getcwd().'/public/docs/trombinoscope.html', $htmlOutput);

		$view = new JsonModel(array(
			'success' => true,
			  'html' => '/docs/trombinoscope.html',
		));

		$view->setTerminal(true);
		return $view;
	}

	##Verification du flag du liste planning quand on save une liste
	public function checkListeFlagAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idListe = $request->getPost('idListe', '');
			$idTypeListe = $request->getPost('idTypeListe', '');
			$utiliser = false;
			$msg = "";

			if ($idTypeListe) {
				$utiliser = $this->getListesTable()->checkListeFlagPlanning($idTypeListe, $idListe);
				if ($utiliser) {
					$listeName = $utiliser->nom;
					$msg = "La liste $listeName est déjà sélectionnée pour le planning, voulez vous sélectionné cette liste à la place ?";
				}
			} else {
				$msg = "Acun type de liste reçu";
			}

			$view = new JsonModel(array(
						'utiliser' => $utiliser,
						'msg' => $msg,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function getAllChampsNonModifiable()
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$champNonModifiableFixe = $this->getChampsNonModifiable();
		$champBaseNonEditable = $this->getTableObjet('champs')->select(array('afficher' => '0'));
		foreach ($champBaseNonEditable as $row) {
			$champNonModifiableFixe[] = $row->code;
		}
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;
		$champsNonModifiableParProfile = $this->getChampCatTable()->getChampsDeProfile($idProfile);
		$champNonModifiable = array_merge($champNonModifiableFixe, $champsNonModifiableParProfile);
		return $champNonModifiable;
	}

	## chargement du formu pour ajouter nun encaissement depuis l'onglet Infos compte
	public function loadFormEncaissementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idResa = $request->getPost('idResa', null);
			$type = $request->getPost('type', '');
			$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
			$loc = null;
			if ($resa) {
				$modesReglement = $this->loadModesRegDeSite($resa->codeSite, $type);
				$loc = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
			} else {
				$modesReglement = array();
			}
			$date = '';
			if ($this->checkDateEncais(date('Y-m-d')) == 'ok') {
				$date = date('d-m-Y');
			}
			$libelle = $type == "remb" ? 'Remboursement '.$loc->nom.' '.$loc->prenom : 'Encaissement '.$loc->nom.' '.$loc->prenom;

			$htmlViewLC = new ViewModel();
			$htmlViewLC->setTerminal(true)
			->setTemplate('reservation/liste/encaisform')
			->setVariables(array(
				'modesReglement' => $modesReglement,
				'idResa' => $idResa,
				'date' => $date,
				'libelle' => $libelle,
				'type' => $type,
			));
			$htmlOP = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewLC);

			$view = new JsonModel(array(
						'htmlOP' => $htmlOP,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	public function ajouterEncaissementAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$msg = "";
			$htmlOP = "";
			$success = false;
			$idResa = $request->getPost('idResa', null);
			$montantCompteCourant = $request->getPost('montantCompteCourant', null);
			$montantCaution = $request->getPost('montantCaution', null);
			$dateEncaissement = $request->getPost('dateEncaissement', null);
			$noPiece = $request->getPost('noPiece', '');

			if (!$montantCaution && !$montantCompteCourant) {
				$msg = "Aucun montant fournis";
			} elseif (!$idResa) {
				$msg = "la param idResa est vide";
			} else {
				$isValideNoPiece = false;
				if ($noPiece) {
					$type = "compte";
					if ($montantCaution && $montantCompteCourant) {
						$type = "compte-caution";
					} elseif ($montantCaution) {
						$type = "caution";
					}
					$isValideNoPiece = $this->checkNoPiece($noPiece, $dateEncaissement, $idResa, $type);
				}
				if ($noPiece && !$isValideNoPiece) {
					$msg = "no pièce $noPiece non valide/unique";
				} else {
					$data = $request->getPost()->toArray();
					//print_r($data);exit();
					$ret = $this->ajouterEncaissement($data);
					//$ret = array('noPiece'=>$noPiece);
					if (is_array($ret)) {
						$lib = $type == 'remb' ? 'Remboursement' : 'Encaissement';
						$msg = "$lib ".$ret['noPiece']." bien crée";
						$success = true;
						$htmlOP = $this->loadComptesTab($idResa);
					} else {
						$msg = $ret;
					}
				}
			}

			$view = new JsonModel(array(
						'msg' => $msg,
						'success' => $success,
						'htmlOP' => $htmlOP,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function ajouterEncaissement($data = array())
	{
		extract($data);

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
		if (!$resa) {
			return "Aucune réservation trouvé avec l'id $idResa";
		}

		$conf = $this->getConfigurationTable()->getConfig(1);
		$return = false;
		if ($conf && $conf->bredea == 1) {
			try {
				$loc = $this->getLocatairesTable()->getLocataire($resa->idLocataire);
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');

				$montant = $montantCompteCourant;
				if ($montantCaution) {
					$montant += $montantCaution;
				}
				$regData = array(	'numTransaction' => '',
								'dateOperation' => $dateEncaissement,
								'numResa' => $resa->numResa,
								'codeSite' => $resa->codeSite,
								'numDossier' => $resa->numDossier,
								'typre' => $resa->typre,
								'modeReglementBredea' => $modeReglement,
								'montantCaution' => $montantCaution,
								'nomLocataire' => $loc->nom,
								'prenomLocataire' => $loc->prenom,
								'typeLigne' => '1',
								'loc' => $loc,
								'montant' => $montant,
								);
				if ($libelleEncaissement) {
					$regData['libelle'] = substr($libelleEncaissement, 0, 60);
				}
				if ($libelleCaution) {
					$regData['libelleCompteCaution'] = substr($libelleCaution, 0, 60);
				}
				if ($libelleCompteCourant) {
					$regData['libelleCompte'] = substr($libelleCompteCourant, 0, 60);
				}
				if ($noPiece) {
					$regData['noPiece'] = $noPiece;
				}

				$log = new Logs();

				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = $type == "remb" ? "Ficher usager : ajout remboursement" : "Ficher usager : ajout encaissement";
				$log->dataBefore = array();
				$log->dataAfter = $regData;
				$log->tableName = "Bredea";
				$log->idReservation = $idResa;
				$log->idLocataire = $loc->id;
				$this->getLogsTable()->saveLogs($log);

				if ($type == "remb") {
					$ret = $bredea->ecrireRemboursement($regData);
					if (is_array($ret)) {
						$bredea->closeConnect();
						return $ret;
					} else {
						$return = $ret;
					}
				} else {
					$noPiece = $bredea->ecrireExtraitCompte($regData);
				}

				if ($noPiece) {
					$bredea->closeConnect();
					return array('noPiece' => $noPiece);
				}
				$bredea->closeConnect();
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $return;
	}

	## formulaire ajout encaissement : verification si la date est bien valide cote bredea
	public function checkDateEncaisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$msg = "";
			$isValide = false;
			$idResa = $request->getPost('idResa', null);
			$date = $request->getPost('date', null);

			if ($date) {
				$ret = $this->checkDateEncais($date);
				if ($ret == 'ok') {
					$isValide = true;
				} else {
					$msg = $ret;
				}
			} else {
				$msg = "Aucune date reçu";
			}

			$view = new JsonModel(array(
						'msg' => $msg,
						'isValide' => $isValide,
			));
			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function checkDateEncais($date)
	{
		$conf = $this->getConfigurationTable()->getConfig(1);
		$return = false;
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
				$return = $bredea->checkDateEncais($date);
				$bredea->closeConnect();
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $return;
	}

	private function checkNoPiece($noPiece, $date, $idResa, $type = 'compte')
	{
		$isValide = false;
		$conf = $this->getConfigurationTable()->getConfig(1);
		$date = date('Ymd', strtotime($date));
		if ($conf && $conf->bredea == 1) {
			try {
				$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();

				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
				if ($type == 'compte') {
					$isValide = $bredea->checkCle('001fhistofac', array('hfa_site' => $resa->codeSite,
												'hfa_dossier' => $resa->numDossier,
												'hfa_date' => $date,
												'hfa_nopiece' => $noPiece,
											));
				} elseif ($type == 'caution') {
					$isValide = $bredea->checkCle('001fcaution', array('cau_site' => $resa->codeSite,
												'cau_dossier' => $resa->numDossier,
												'cau_date' => $date,
												'cau_nopiece' => $noPiece,
											));
				} elseif ($type = "compte-caution") {
					$isValideCompte = $bredea->checkCle('001fhistofac', array('hfa_site' => $resa->codeSite,
												'hfa_dossier' => $resa->numDossier,
												'hfa_date' => $date,
												'hfa_nopiece' => $noPiece,
											));
					$isValideCaution = $bredea->checkCle('001fcaution', array('cau_site' => $resa->codeSite,
												'cau_dossier' => $resa->numDossier,
												'cau_date' => $date,
												'cau_nopiece' => $noPiece,
											));
					$isValide = $isValideCompte && $isValideCaution;
				}

				$bredea->closeConnect();
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $isValide;
	}

	## chargement des modes de réglement par site
	public function loadModesRegDeSite($codeSite, $type = '')
	{
		$return = array();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');
				$typeMR = ($type == "remb") ? 'P' : 'E';
				$return = $bredea->loadModeRegParSite(array($codeSite), $typeMR);
				$bredea->closeConnect();
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Exception=".$ex->getMessage());
				echo $ex->getMessage();
			}
		}
		return $return;
	}

	## Action
	public function exportListeForMailAction()
	{
		$mesParams	= $this->getEvent()->getRouteMatch()->getParam('mesParams');
		$idListe = $modeListe = null;
		$saveFile = true;
		if (is_array($mesParams)) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : mesParams=".json_encode($mesParams));
			$idListe		= $mesParams['idListe'];
			$modeListe		= $mesParams['modeListe'];
			$saveFile		= array_key_exists('saveFile', $mesParams) ? $mesParams['saveFile'] : true;
			$extraParams    = array_key_exists('extraParams', $mesParams) ? $mesParams['extraParams'] : array();
		}
		$fileName = '';
		if ($idListe && $modeListe) {
			$fileName = $this->getExportListeForMail($idListe, $modeListe, $saveFile, $extraParams);
		}
		return $fileName;
	}
	## Fonction qui génère l'export excel d'une liste, pour l'attacher à un mail
	public function getExportListeForMail($idListe, $modeListe, $saveFile = true, $extraParams = array())
	{
		// Fichier généré enregistré dans /docs/pj
		$tools = new Tools();
		if ($idListe && $modeListe) {
			$modesCleUrl = $this->getGlobalHelper()->getModesCleUrl();
			if(!empty($modesCleUrl[$modeListe])) {
				$modeListe = $modesCleUrl[$modeListe];
			}
			$liste = null;
			$formFields = array();
			$modeExport = '';
			if($modeListe == 'reservations') {
				$liste = $this->getListesTable()->getListe($idListe);
				$listeState = $this->loadResaState($idListe);
				$formFields     = $this->getResaFields($idListe, array());
				if(!empty($extraParams)) {
					$modeExport = 'statsListe';
				}
			} elseif($modeListe == 'dp') {
				$liste = $this->getTableObjet('domiciliations_listes')->select(array('id' => $idListe))->current();
				$listeState = $this->loadDomiciliationsState($idListe);
				$formFields     = $this->getDpFields($idListe, array());
				if(!empty($extraParams)) {
					$modeExport = 'statsListeDP';
				}
			} elseif($modeListe == 'demandes') {

				$liste = $this->getTableObjet('demandes_listes')->select(array('id' => $idListe))->current();

				$listeStateForward = $this->forward()->dispatch('Reservation\Controller\Demandes', array(
					'action' => 'getDemandesStateForward',
					'params'	=> array('idListe' => $idListe),
				));
				$listeState = $listeStateForward->getVariables();

				$formFieldsForward = $this->forward()->dispatch('Reservation\Controller\Demandes', array(
					'action' => 'getDemandesFieldsForward',
					'params'	=> array('idListe' => $idListe),
				));
				$formFields = $formFieldsForward->getVariables();

				if(!empty($extraParams)) {
					$modeExport = 'statsListeDemandes';
				}
			}
			$fields = array();
			foreach($formFields as $type => $fieldArr) {
				$fields = array_merge($fields, $fieldArr);
			}
			if($liste) {
				$columns = array();
				$columns[0] = array();//pour garder le bon ordre de colonnes
				$order = array();
				$cols = !empty($listeState['filter']) ? $listeState['filter'] : array();
				$orders = !empty($listeState['order']) ? $listeState['order'] : array();
				$i = 0;
				$header = array();
				$headerCols = array();

				if ($modeListe == 'demandes') {
					foreach ($cols as $groupCol => $opts) {
						foreach ($opts as $colName => $opt) {
							$columns[] = array(
								'data' => $colName,
								'name' => $colName,
								'searchable' => 'true',
								'orderable' => 'true',
								'search' => array('value' => $opt['search']),
							);

							$libCol = $colName;
							if(array_key_exists($colName, $fields) && $fields[$colName]->nom) {
								$libCol = $fields[$colName]->nom;
							}
							$header[] = utf8_decode($libCol);
							$headerCols[] = $colName;
						}
					}
				} else {
					foreach ($cols as $colName => $opts) {
						$columns[] = array('data' => $colName,
											'name' => $colName,
											'searchable' => true,
											'orderable' => true,
											'search' => array('value' => $opts['search']),
											);
						$libCol = $colName;
						if(array_key_exists($colName, $fields) && $fields[$colName]->nom) {
							$libCol = $fields[$colName]->nom;
						}
						$header[] = utf8_decode($libCol);
						$headerCols[] = $colName;
					}
				}

				foreach ($orders as $o) {
					$order[] = array('column' => $o[0], 'dir' => $o[1]);
				}

				$data = array('idListe' => $idListe,
								'columns' => $columns,
								'order' => $order,
								'start' => '0',
								'length' => '-1',
								'typeAppel' => 'modeIndicateurs',
								);
				$this->request->setMethod('POST')->setPost(new Parameters($data));
			}
			$ret = array();
			if($modeListe == 'reservations') {
				$ret = $this->getServerJsonDataAction();
			} elseif($modeListe == 'dp') {
				$ret = $this->getServerJsonDataDpAction();
			} elseif($modeListe == 'demandes') {
				if ($modeExport == 'statsListeDemandes') {
					$ret = $this->getServerJsonDataForward($idListe, "demandes", "ext");
				} else {
					$ret = $this->getServerJsonDataForward($idListe, "demandes");
				}
			}
			if (!empty($ret)) {
				$dataListe = !empty($ret['data']) ? $ret['data'] : 0;
				$data = array();
				foreach($dataListe as $d) {
					$l = array();
					foreach($headerCols as $colName) {
						$l[] = !empty($d[$colName]) ? utf8_decode($d[$colName]) : '';
					}
					if(!empty($l)) {
						$data[] = $l;
					}
				}
				//print_r($data);exit();
				$listeName = $liste ? $liste->nom : 'liste';
				$listeName = $tools->removeAccent($listeName);
				$listeName .= '_'.$idListe;

				$idsModeleStats = array();
				$typesSuivisInFile = array();
				if ($liste->stats == '1') {

					if ($modeListe == 'reservations') {
						$modelesListe = $this->getTableObjet('stats_modeles_liste')->select(array('idListe' => $idListe, 'tableListes' => 'listes'))->toArray();
					} elseif ($modeListe == 'dp') {
						$modelesListe = $this->getTableObjet('stats_modeles_liste')->select(array('idListe' => $idListe, 'tableListes' => 'dp_listes'))->toArray();
					}

					if ($modelesListe) {
						foreach ($modelesListe as $modeleListe) {
							$idsModeleStats[] = $modeleListe['idModele'];
							$typesSuivisModele = $this->getTableObjet('stats_modeles_type_suivis')->select(array('idModele' => $modeleListe['idModele']))->toArray();
							if ($typesSuivisModele) {
								foreach ($typesSuivisModele as $typeSuivisModele) {
									$typesSuivisInFile[] = $this->getTableObjet('type_suivi')->select(array('id' => $typeSuivisModele['idTypeSuivis']))->current();
								}
							}

						}
					}
				}

				$this->outputExcel($data, $header, $listeName, $saveFile, $modeExport, $idListe, $typesSuivisInFile, $idsModeleStats, $extraParams);

				if ($extraParams['modeEXT'] == 'EXT') {
					return true;
				} else {
					return $listeName.'_'.date('d-m-Y-His').'.xls';
				}
			}
		}
		return '';
	}

	##Appel depuis le dashboard : Recup nombre de lignes d'une liste
	public function dashboardlisteAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$count = '...';
			$idListe = $request->getPost('id', null);
			if ($idListe) {
				$listeState = $this->loadResaState($idListe);
				$columns = array();
				$order = array();
				$cols = !empty($listeState['filter']) ? $listeState['filter'] : array();
				$orders = !empty($listeState['order']) ? $listeState['order'] : array();
				$i = 0;
				foreach ($cols as $colName => $opts) {
					$columns[] = array('data' => $colName,
										'name' => $colName,
										'searchable' => true,
										'orderable' => true,
										'search' => array('value' => $opts['search']),
										);
				}

				foreach ($orders as $o) {
					$order[] = array('column' => $o[0], 'dir' => $o[1]);
				}


				$data = array('idListe' => $idListe,
								'columns' => $columns,
								'order' => $order,
								'start' => '0',
								'length' => '-1',
								'typeAppel' => 'controller',
								);
				$this->request->setMethod('POST')->setPost(new Parameters($data));

				$ret = $this->getServerJsonDataAction();
				if (!empty($ret)) {
					$count = !empty($ret['recordsFiltered']) ? $ret['recordsFiltered'] : 0;
				}
			}


			$baseUrl = $this->getBaseUrl();
			if (substr($baseUrl, -1, 1) == '/') {
				$url = $baseUrl."admin/liste/$idListe/reservations";
			} else {
				$url = $baseUrl."/admin/liste/$idListe/reservations";
			}
			$htmlOP = '<span class="badge"><a class="text-white" href="'.$url.'" target="_blank">'.$count.'</a></span>';
			$view = new JsonModel(array(
				'success'	=> $success,
				'htmlOP'	=> $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	##Appel depuis le dashboard : Recup nombre de lignes d'une liste
	public function dashboardlistedpAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$count = '...';
			$idListe = $request->getPost('id', null);
			if ($idListe) {
				$listeState = $this->loadDomiciliationsState($idListe);
				$columns = array();
				$order = array();
				$cols = !empty($listeState['filter']) ? $listeState['filter'] : array();
				$orders = !empty($listeState['order']) ? $listeState['order'] : array();
				$i = 0;
				foreach ($cols as $colName => $opts) {
					$columns[] = array('data' => $colName,
										'name' => $colName,
										'searchable' => true,
										'orderable' => true,
										'search' => array('value' => $opts['search']),
										);
				}

				foreach ($orders as $o) {
					$order[] = array('column' => $o[0], 'dir' => $o[1]);
				}


				$data = array('idListe' => $idListe,
								'columns' => $columns,
								'order' => $order,
								'start' => '0',
								'length' => '-1',
								'typeAppel' => 'controller',
								);
				$this->request->setMethod('POST')->setPost(new Parameters($data));

				$ret = $this->getServerJsonDataDpAction();
				if (!empty($ret)) {
					$count = !empty($ret['recordsFiltered']) ? $ret['recordsFiltered'] : 0;
				}
			}


			$baseUrl = $this->getBaseUrl();
			if (substr($baseUrl, -1, 1) == '/') {
				$url = $baseUrl."admin/liste/$idListe/dp";
			} else {
				$url = $baseUrl."/admin/liste/$idListe/dp";
			}
			$htmlOP = '<span class="badge"><a class="text-white" href="'.$url.'" target="_blank">'.$count.'</a></span>';
			$view = new JsonModel(array(
				'success'	=> $success,
				'htmlOP'	=> $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function saveMenageHistorique($idResa, $idAncienMenage, $idNouveauMenage, $typeChangement='')
	{
		if ($idAncienMenage != $idNouveauMenage) {
			if (!$idAncienMenage) {
				$idAncienMenage = '0';
			}
			$data = array('idResa' => $idResa,
						'idAncienMenage' => $idAncienMenage,
						'idNouveauMenage' => $idNouveauMenage,
						'dateChangement' => date('Y-m-d H:i:s'),
						'typeChangement' => $typeChangement,
						);
			$this->getTableObjet('historique_menage')->insert($data);
		}
	}

	public function loadMenagesTab($idResa)
	{
		$rows = array();

		$result = $this->getTableObjet('menages')->select();
		$menages = array();
		foreach ($result as $r) {
			$menages[$r->id] = $r->nom;
		}
		$rows = $this->getTableObjet('historique_menage')->select(array('idResa' => $idResa));
		$htmlViewPart = new ViewModel();
		$htmlViewPart->setTerminal(true)
		->setTemplate('reservation/liste/historiquemenage')
		->setVariables(array(
				"rows" => $rows,
				"idResa" => $idResa,
				"menages" => $menages,
		));

		$htmlOutput = $this->getServiceLocator()
		->get('viewrenderer')
		->render($htmlViewPart);

		return $htmlOutput;
	}

	private function majDatesTheoriques($idResa)
	{
		$resa = $this->getResaTable()->getResa($idResa);
		if (!$resa) {
			return;
		}

		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($conf && $conf->bredea == 1) {
			try {
				$bredea	= null;
				if ($resa && $resa->numDossier) {
					$this->initPMS($resa->idApiPms ?: 1, $idResa);

					## Traitement en fonction du PMS
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($this->pms) {
						if ($this->pms->getClassName() === "Bredea") {
							$bredea	= $this->pms;
						} elseif ($this->pms->getClassName() === "CeriFoyer") {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idResa=$idResa PMS CeriFoyer : TODO");
						}
					}
				}
				if (!$bredea) {
					return;
				}

				$typeFacturation = $conf->typeFacturation;
				$dateDebutFact = $conf->dateDebutFact;
				$return = $bredea->majDatesFacturation($resa->numDossier, $resa->codeSite, $resa->typre, array('typeFacturation' => $typeFacturation, 'dateDebutFact' => $dateDebutFact));

				//on maj les dates theorique
				$upData = array();
				if (!empty($return['dateArriveeTheorique']) && !$resa->idAncienneResa) {
					$upData['dateArriveeTheorique'] = date('Y-m-d', strtotime($return['dateArriveeTheorique']));
				}
				if (!empty($return['dateDepartTheorique']) && !$resa->idNouvelleResa) {
					$upData['dateDepartTheorique'] = date('Y-m-d', strtotime($return['dateDepartTheorique']));

					// changement de flags notification caf
					$upData['cafChangementDateDepartTheorique'] = '1';
				}

				if (!empty($upData)) {
					$this->getResaTable()->updateResa($upData, array('id' => $idResa));
				}
			} catch (\Exception $ex) {
				echo $ex->getMessage();
			}
		}
	}

	public function relanceODCautionAction()
	{
		//$bredea = $this->getGlobalHelper()->getPMSObjectByClassName('Bredea');

		$idResa = 1152;
		$date = '20210125';

		$resa = $this->getResaTable()->getResaWithPms($idResa);
		$bredea = null;
		if ($resa) {
			$this->initPMS($resa->idApiPms ?: 1, $idResa);

			## Traitement en fonction du PMS
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			if ($this->pms) {
				if ($this->pms->getClassName() === "Bredea") {
					$bredea	= $this->pms;
				} elseif ($this->pms->getClassName() === "CeriFoyer") {
					## Rien à faire pour l'instant
				}
			}
		}

		if ($bredea) {
			try {
				$tableResa = $this->getTableObjet('reservations');
				$tableComptes = $this->getTableObjet('comptes');

				//$resa = $tableResa->select(array('id'=>$idResa))->current();
				$resa =  $this->getResaTable()->getResa($idResa);

				$comptes = $tableComptes->select(array('idReservation' => $idResa));
				foreach ($comptes as $c) {
					if ($c->type == 4 && $c->etat == 1) {

						//$regData['montantCaution'] = $c->solde;
						//on cree la ligne caution
						$cDataCaution = array();
						$cDataCaution['numDossier'] = $resa->numDossier;
						$cDataCaution['typre'] = $resa->typre ? $resa->typre : 'R';
						$cDataCaution['codeSite'] = $resa->codeSite;
						$cDataCaution['montantCaution'] = $c->debit;
						$cDataCaution['date'] = $date;
						$cDataCaution['modeReglement'] = 'OD';
						## on recup le montant d'acompte 001facompte : acomp_site, acomp_dossier, acomp_mteuro
						$aCompte = $bredea->getRow('001facompte', array('acomp_site' => $resa->codeSite, 'acomp_dossier' => $resa->numResa));
						if (!empty($aCompte) && !empty($aCompte['acomp_mtcaution'])) {
							$cDataCaution['montantCaution']	= $aCompte['acomp_mtcaution'];
						}

						$noPieceCaution = $bredea->creationODAcompteCaution($cDataCaution);

						$log = new Logs();
						$log->dateOperation = date('Y-m-d H:i:s');
						$log->idGestionnaire = 0;
						$log->operation = "CheckIN creation caution de résa $idResa";
						$log->dataBefore = array();
						$log->dataAfter = $cDataCaution;
						$log->tableName = "Bredea";
						$log->idLocataire = $resa->idLocataire;
						$log->idReservation = $resa->id;
						$this->getLogsTable()->saveLogs($log);
					}
				}
			} catch (\Exception $ex) {
				$bredea->closeConnect();
				echo $ex->getMessage();
			}
			$bredea->closeConnect();
			echo "OK";
		}
		exit();
	}


	public function inactiviteEnCours($idDp)
	{
		$ret = false;
		if ($idDp) {
			$idTypeSuivis = 12;//libre_Fin_inactivite   libre_Date_debut_inactivite
			$now = date('Y-m-d');
			$tableSuivisVal = $this->getTableObjet('suivis_values');
			$tableChampsSuivis = $this->getTableObjet('champs_suivis');
			$tableSuivis = $this->getTableObjet('suivis');

			$whereCF = array('champs_suivis.equivalentSql' => 'libre_Date_debut_inactivite', 'champs_suivis.idTypeSuivis' => $idTypeSuivis);
			$champDate1 = $tableChampsSuivis->select($whereCF)->current();

			$whereCF = array('champs_suivis.equivalentSql' => 'libre_Fin_inactivite', 'champs_suivis.idTypeSuivis' => $idTypeSuivis);
			$champDate2 = $tableChampsSuivis->select($whereCF)->current();

			if ($champDate1 && $champDate2) {
				$select = $tableSuivisVal->getSql()->select();
				$select->join('suivis', 'suivis.id = suivis_values.idSuivis', array('idS' => 'id'));
				$select->where(array('suivis.idTypeSuivis' => $idTypeSuivis, 'suivis.idDp' => $idDp, 'suivis.archive' => '0', 'suivis.deleted' => '0'));
				$rows = $tableSuivisVal->selectWith($select);
				$dates = array();
				foreach ($rows as $row) {
					if ($row->idChamp == $champDate1->id && $row->valeur) {
						$dates[$row->idSuivis]['dateDebut'] = date('Y-m-d', strtotime($row->valeur));
					}
					if ($row->idChamp == $champDate2->id && $row->valeur) {
						$dates[$row->idSuivis]['dateFin'] = date('Y-m-d', strtotime($row->valeur));
					}
				}
				foreach ($dates as $r) {
					if (!$ret && strtotime($r['dateDebut']) <= strtotime($now) && strtotime($now) < strtotime($r['dateFin'])) {
						$ret = true;
					} elseif (!$ret && strtotime($r['dateDebut']) <= strtotime($now) && !array_key_exists('dateFin', $r)) {
						$ret = true;
					}
				}
			}
		}
		return $ret;
	}



	## on recup le form de la situation à la sortie pour gammes
	private function getFormSitSortie($idCampagne)
	{
		if (!$idCampagne) {
			return null;
		}
		$champName = "libre_Date_de_sortie";
		$tableCF = $this->getTableObjet('champs_formulaires');

		$select = $tableCF->getSql()->select();
		$select->join('formulaires', 'champs_formulaires.idFormulaire = formulaires.id', array('idFrom' => 'id', 'idCampagne'));
		$select->where(array('champs_formulaires.equivalentSql' => $champName,
								'champs_formulaires.active' => '1',
								'formulaires.idCampagne' => $idCampagne,
								));
		$row = $tableCF->selectWith($select)->current();

		return $row ? $row->idFormulaire : null;
	}

	## dé-archivage domicialiations
	public function deArchiverDpAction()
	{
		$request = $this->getRequest();
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		if ($request->isXmlHttpRequest()) {
			$idsDp = $request->getPost('ids', array());
			$idsToCreate = array();

			$success = true;
			$msg = $msgSuccess = $msgErrors = $toCreateMsg = "";
			$tableDp = $this->getTableObjet('domiciliations');
			foreach ($idsDp as $idDp) {
				$dp = $tableDp->select(array('id' => $idDp))->current();

				$tableDp->update(array('archive' => '0'), array('id' => $idDp));

				### save logs
				$log = new Logs();
				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = "BO Dé-archivage domiciliation $idDp";
				$log->dataBefore = array('archive' => '1');
				$log->dataAfter = array('archive' => '0');
				$log->tableName = "domiciliations";
				$log->idLocataire = $dp->idLocataire;
				$this->getLogsTable()->saveLogs($log);

				$msg .= "Domiciliation bien dé-archivée ID $idDp<br>";
			}

			$view = new JsonModel(array(
						'success' => true,
						'msg' => $msg,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}


	## vérification disponibilité stock logement CS lors de changement de dates,
	private function isBloquerCS($idLogement, $dateArrivee, $dateDepart)
	{
		$dateArrivee = date('Y-m-d', strtotime($dateArrivee));
		$dateDepart = date('Y-m-d', strtotime($dateDepart));
		$msg = '';

		$tableStockCS = $this->getTableObjet('stockCS2logement');

		$select = $tableStockCS->getSql()->select();
		$select->join('stocksCS', 'stockCS2logement.idStock = stocksCS.id', array('idS' => 'id', 'debutBlocage', 'finBlocage'));
		$select->where(array('stockCS2logement.idLogement' => $idLogement, 'stocksCS.deleted' => '0'));
		$select->where('stocksCS.debutBlocage < \''.$dateDepart.'\' AND stocksCS.finBlocage > \''.$dateArrivee.'\'');
		$row = $tableStockCS->selectWith($select)->current();
		if ($row) {
			$msg = 'Logement bloquer court séjour entre le '.date('d-m-Y', strtotime($row['debutBlocage'])).' et '.date('d-m-Y', strtotime($row['finBlocage']));
		}
		return $msg;
	}

	## Script pour corriger les durée IC et décalage
	public function correctionDureeICAction()
	{
		$all = (isset($_GET['all']) && $_GET['all'] == '1') ? true : false;
		$simul = (isset($_GET['simul']) && $_GET['simul'] != "") ? true : false;
		$simulMsg = $simul ? " (simulation) " : "";
		$idResa = (isset($_GET['idResa']) && $_GET['idResa'] != "" && $_GET['idResa'] > 0) ? $_GET['idResa'] : null;

		$j = 0;

		$tableResa = $this->getTableObjet('reservations');
		$tableLoc = $this->getTableObjet('locataires');
		$tableEtatIC = $this->getTableObjet('etat_intercontrat');
		$tableIC = $this->getTableObjet('intercontrat');

		$select = $tableEtatIC->getSql()->select();
		$select->order(array('ordre asc'));
		$allEtatREsult = $tableEtatIC->selectWith($select);
		$allEtatIC = array();
		foreach ($allEtatREsult as $i) {
			$allEtatIC[$i->id] = $i;
		}

		$select = $tableResa->getSql()->select();
		$select->where(array('etat' => 6, 'archive' => '0'));
		if ($idResa) {
			$select->where(array('id' => $idResa));
		} else {
			if (!$all) {
				$select->where("dateDepart >= '2020-01-01'");
			}
		}
		$resas = $tableResa->selectWith($select);

		foreach ($resas as $resa) {
			$select = $tableIC->getSql()->select();
			$select->where(array('idReservation' => $resa->id/*,'valide'=>'1'*/));
			$select->order(array('dateEtat asc', 'id ASC'));
			$etatICRows = $tableIC->selectWith($select);
			$i = 1;
			$prevEtatDeResa = array();
			foreach ($etatICRows as $etatIC) {
				if ($i > 1) {
					$prevEtat = !empty($prevEtatDeResa[$i - 1]) ? $prevEtatDeResa[$i - 1] : null;
					if ($prevEtat) {
						$upData = array();
						$dateEtatPrecedente = $prevEtat->dateEtat;
						$dateValidationIC = $etatIC->dateEtat;
						$datePrev = new \DateTime($dateEtatPrecedente);
						$dateActuel = new \DateTime($dateValidationIC);
						$difference = $datePrev->diff($dateActuel);
						$duree = $difference->format('%a');

						//on calcule le retard
						$configDuree = $this->getDuree($resa->id, $prevEtat->idEtat, $exclureICResa = true);
						$decalage = $configDuree - $duree;
						//echo "decalage $decalage = configDuree $configDuree - duree $duree <br>";

						if ($duree != $prevEtat->duree) {
							$upData['duree'] = $duree;
							$nomEtat = utf8_decode($allEtatIC[$prevEtat->idEtat]->nom);
							echo "$simulMsg Ligne ".$prevEtat->id." Duree de l etat $nomEtat maj DE ".$prevEtat->duree." EN $duree pour la resa ".$prevEtat->idReservation."<br>";
						}

						if ($decalage != $prevEtat->decalage) {
							$upData['decalage'] = $decalage;
							$nomEtat = utf8_decode($allEtatIC[$prevEtat->idEtat]->nom);
							echo "$simulMsg Ligne ".$prevEtat->id." Decalage de l etat $nomEtat maj DE ".$prevEtat->decalage." EN $decalage pour la resa ".$prevEtat->idReservation."<br>";
						}

						if (!empty($upData)) {
							if (!$simul) {
								$tableIC->update($upData, array('id' => $prevEtat->id));
							}
							$j++;
						}
					}
					$prevEtatDeResa[$i] = $etatIC;
				} else {
					$prevEtatDeResa[$i] = $etatIC;
				}
				$i++;
			}
		}
		echo "Terminer<br> $j lignes maj";
		exit();
	}

	public function recherchestricteAction()
	{
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : ");
		$request = $this->getRequest();
		$conf = $this->getConfigurationTable()->getConfig(1);
		if ($request->isXmlHttpRequest()) {
			$rechercheStricte_nom		= $request->getPost('rechercheStricte_nom');
			$rechercheStricte_prenom	= $request->getPost('rechercheStricte_prenom');
			$rechercheStricte_dateNaissance = $request->getPost('rechercheStricte_dateNaissance');
			$rechercheStricte_archive	= $request->getPost('rechercheStricte_archive');
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : POST=".json_encode($request->getPost()));

			if (($absenceDateNaissance = !$rechercheStricte_dateNaissance)) {
				$from	= $request->getPost('from');
				if ($from == 'resa') {
					$absenceDateNaissance	= ($_SESSION['USERDROIT']['liste-input-mode-liste-recherche-stricte-date-naissance-facultative'] != 'W');
				} elseif ($from == 'dp') {
					$absenceDateNaissance	= ($_SESSION['USERDROIT']['mode-input-dp-recherche-stricte-date-naissance-facultative'] != 'W');
				}
			}
			if (!$rechercheStricte_nom || !$rechercheStricte_prenom || $absenceDateNaissance) {
				## Les champs sont obligatoires
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$view = new JsonModel(array(
					'success'	=> false,
					'htmlOP'	=> "<div class='erreurRechercheStricte'>Les paramètres sont obligatoires</div>",
				));

				$view->setTerminal(true);
				return $view;
			}

			## Recherche de demandes pour ces champs strictement
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			## Lecture des reservations
			## ~~~~~~~~~~~~~~~~~~~~~~~~
			$resas	= array();
			try {
				$where = array(	'locataires.nom'		=> $rechercheStricte_nom,
						'locataires.prenom'		=> $rechercheStricte_prenom,
						);
				if ($rechercheStricte_dateNaissance) {
					$where['locataires.dateNaissance']	= $rechercheStricte_dateNaissance;
				}
				if ($rechercheStricte_archive == 'false') {
					$where['reservations.archive']		= '0';
				}

				$resas = $this->getResaTable()->getResaBy($where, $avecGroup = false, $avecLocataire = true,array(), $avecLogement = true);
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : getResaBy Exception=".$ex->getMessage());
			}

			## Lecture des domiciliations
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~
			$dps	= array();
			try {
				$where = array(	'locataires.nom'		=> $rechercheStricte_nom,
						'locataires.prenom'		=> $rechercheStricte_prenom,
						);
				if ($rechercheStricte_dateNaissance) {
					$where['locataires.dateNaissance']	= $rechercheStricte_dateNaissance;
				}
				if ($rechercheStricte_archive == 'false') {
					$where['domiciliations.archive'] = '0';
				}
				$dps = $this->getDomiciliationsTable()->getDomiciliationBy($where, $avecLocataire = true);
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : getDomiciliationBy Exception=".$ex->getMessage());
			}

			## Lecture des campagnes
			## ~~~~~~~~~~~~~~~~~~~~~
			$campagnes	= array();
			try {
				$campagnes1 = $this->getCampagneTable()->fetchAll();
				foreach ($campagnes1 as $r) {
					$campagnes[$r->id] = $r->nom;
				}
			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : getCampagnes Exception=".$ex->getMessage());
			}


			## Construction de la liste à partir des réservations et domiciliations
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$tableValDyn = $this->getTableObjet('valeurs_dynamiques');
			$tableModeCamp = $this->getTableObjet('modes_campagne');
			$tableValSel = $this->getTableObjet('valeurs_select');
			$tableUser = $this->getTableObjet('user');
			$tableResa = $this->getTableObjet('reservations');
			$rows	= array();
			if ($resas) {
				foreach ($resas as $resa) {
					$referent = '';
					$dateEntree = $resa->dateArrivee;
					$dateSortie = $resa->dateDepart;

					// champs dates entrée et sortie, selon les champs configuré dans les param campagnes
					$modeCamp = $tableModeCamp->select(array('idCampagne' => $resa->idCampagne))->current();
					if ($modeCamp) {
						if ($modeCamp->idChampDateArriveeRS) {
							$dateEntree = '';
							$val = $tableValDyn->select(array('idChamp' => $modeCamp->idChampDateArriveeRS, 'idReservation' => $resa->id))->current();
							if ($val) {
								$dateEntree = $val->valeur;
							}
						}
						if ($modeCamp->idChampDateDepartRS) {
							$dateSortie = '';
							$val = $tableValDyn->select(array('idChamp' => $modeCamp->idChampDateDepartRS, 'idReservation' => $resa->id))->current();
							if ($val) {
								$dateSortie = $val->valeur;
							}
						}
						## champ référent
						if ($modeCamp->idChampReferentRS) {
							$select = $tableValDyn->getSql()->select();
							$select->join('champs_formulaires', 'valeurs_dynamiques.idChamp = champs_formulaires.id', array('idChamp' => 'id', 'sourceListe'));
							$select->where(array('valeurs_dynamiques.idChamp' => $modeCamp->idChampReferentRS, 'valeurs_dynamiques.idReservation' => $resa->id));
							$val = $tableValDyn->selectWith($select)->current();
							if ($val) {
								$referent = $val->valeur;
								if(is_numeric($val->sourceListe)){
									$valSel = $tableValSel->select(array('id'=>$val->valeur))->current();
									$referent = $valSel ? $valSel->valeur : $referent;
								}elseif($val->sourceListe == 'user'){
									$valSel = $tableUser->select(array('user_id'=>$val->valeur))->current();
									$referent = $valSel ? $valSel->display_name : $referent;
								}
							}
						}
					}

					## recherche site chef de ménage si pas de logement pour le membre
					if($resa->idMenage && !$resa->residence && $resa->idStatutFamilial != 1){
						$select = $tableResa->getSql()->select();
						$select->join('logements', 'logements.id = reservations.idLogement', array('idLogement' => 'id', ), 'LEFT');
						$select->join('batiments', 'batiments.id = logements.idBatiment', array('batiment' => 'nom', 'idBatiment' => 'id'), 'LEFT');
						$select->join('residences', 'residences.id = batiments.idResidence', array('residence' => 'nom', 'idResidence' => 'id'), 'LEFT');
						$select->where(array('reservations.idMenage' => $resa->idMenage, 'reservations.idStatutFamilial' => 1,'reservations.archive' => '0'));
						$resaDeChefFamille = $tableResa->selectWith($select)->current();
						if($resaDeChefFamille && $resaDeChefFamille->residence){
							$resa->residence = $resaDeChefFamille->residence;
						}
					}

					$rows[]	= array(
							'isResa'	=> true,
							'idResa'	=> $resa->id,
							'nom'		=> $resa->nomLocataire,
							'prenom'	=> $resa->prenomLocataire,
							'dateNaissance'	=> $resa->dateNaissance,
							'idCampagne'	=> $resa->idCampagne,
							'campagne'	=> $campagnes[$resa->idCampagne],
							'dateEntree'	=> $dateEntree,
							'dateSortie'	=> $dateSortie,
							'etat'		=> $resa->etat,
							'archive'	=> $resa->archive,
							'residence' => $resa->residence,
							'referent' => $referent,
							);
				}
			}
			if ($dps) {
				foreach ($dps as $dp) {
					$dateEntree = $dp->dateEntree;
					$dateSortie = $dp->dateSortie;
					$referent = '';

					// champs dates entrée et sortie, selon les champs configuré dans les param campagnes
					$modeCamp = $tableModeCamp->select(array('idCampagne' => $dp->idCampagne))->current();
					if ($modeCamp) {
						if ($modeCamp->idChampDateArriveeRS) {
							$dateEntree = '';
							$val = $tableValDyn->select(array('idChamp' => $modeCamp->idChampDateArriveeRS, 'idDp' => $dp->id))->current();
							if ($val) {
								$dateEntree = $val->valeur;
							}
						}
						if ($modeCamp->idChampDateDepartRS) {
							$dateSortie = '';
							$val = $tableValDyn->select(array('idChamp' => $modeCamp->idChampDateDepartRS, 'idDp' => $dp->id))->current();
							if ($val) {
								$dateSortie = $val->valeur;
							}
						}
						## champ référent
						if ($modeCamp->idChampReferentRS) {
							$select = $tableValDyn->getSql()->select();
							$select->join('champs_formulaires', 'valeurs_dynamiques.idChamp = champs_formulaires.id', array('idChamp' => 'id', 'sourceListe'));
							$select->where(array('valeurs_dynamiques.idChamp' => $modeCamp->idChampReferentRS, 'valeurs_dynamiques.idReservation' => $dp->id));
							$val = $tableValDyn->selectWith($select)->current();
							if ($val) {
								$referent = $val->valeur;
								if(is_numeric($val->sourceListe)){
									$valSel = $tableValSel->select(array('id'=>$val->valeur))->current();
									$referent = $valSel ? $valSel->valeur : $referent;
								}elseif($val->sourceListe == 'user'){
									$valSel = $tableUser->select(array('user_id'=>$val->valeur))->current();
									$referent = $valSel ? $valSel->display_name : $referent;
								}
							}
						}
					}
					$rows[]	= array(
							'isResa'	=> false,
							'idResa'	=> $dp->id,
							'nom'		=> $dp->nomLocataire,
							'prenom'	=> $dp->prenomLocataire,
							'dateNaissance'	=> $dp->dateNaissance,
							'idCampagne'	=> $dp->idCampagne,
							'campagne'	=> $campagnes[$dp->idCampagne],
							'dateEntree'	=> $dateEntree,
							'dateSortie'	=> $dateSortie,
							'etat'		=> $dp->etat,
							'archive'	=> $dp->archive,
							'residence' => '',
							'referent' => $referent,
							);
				}
			}

			if (!$rows) {
				$view = new JsonModel(array(
					'success'	=> true,
					'htmlOP'	=> "<div class='erreurRechercheStricte'>Pas de dossier pour $rechercheStricte_nom $rechercheStricte_prenom</div>",
				));

				$view->setTerminal(true);
				return $view;
			}

			## Mise en forme du tableau des dossiers
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$htmlView = new ViewModel();
			$htmlView	->setTerminal(true)
					->setTemplate('reservation/liste/rechercheStricte')
					->setVariables(array(
							'rows' => $rows,
						));
			$htmlOP = $this->getServiceLocator()
					->get('viewrenderer')
					->render($htmlView);

			$view = new JsonModel(array(
				'success'	=> true,
				'htmlOP'	=> $htmlOP,
			));

			$view->setTerminal(true);
			return $view;
		}
	}

	public function calculerFormulePrestationAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idTypeSuivis = (int) $request->getPost('idTypeSuivis');
			$idChamp = (int)$request->getPost('idChamp');
			$idResa = (int)$request->getPost('idResa');
			$idDp = (int)$request->getPost('idDp');
			$idChampEdit = (int)$request->getPost('idChampEdit');//quand on edit un champ dans le form suivis
			$valeur = $request->getPost('valeur', '');
			$valChampEdit = $request->getPost('valChampEdit', '');
			$champs = $request->getPost('champs');

			$champ = $this->getTableObjet('champs_suivis')->select(array('id' => $idChamp))->current();

			$valeurs = [];
			// var_dump($champ);die();
			// var_dump($champ['idChamp']);die();
			// $idChamp = $c['idChamp'];
			// $valeur = $c['valeur'];

			$autreValeurs = array();
			if ($champ && $idTypeSuivis) {
				$data = array();

				foreach ($champs as $key => $c) {
					$data['champs_suivis|'.$c['idChamp']] = $c['valeur'];
				}

				// if($idChampEdit){
				// 	$data['champs_suivis|'.$idChampEdit] = $valChampEdit;
				// 	// $data['champs_suivis|'.$c['idChamp']] = $c['valeur'];
				// }

				$valeur = $this->getFormuleExcelTable()->calculerFormule($champ->formule, $idTypeSuivis, $idResa, $idDp, $data, $adapter);
				// var_dump($valeur);die();
				if ($valeur || $valeur == 0) {
					$champsDeFormule = $this->getTableObjet('champs_suivis')->select(array('idTypeSuivis' => $idTypeSuivis, 'idType' => 21));
					foreach ($champsDeFormule as $c) {
						if ($c->id != $idChamp) {
							// $data['champs_suivis|'.$idChamp] = $valeur;
							$valeur2 = $this->getFormuleExcelTable()->calculerFormule($c->formule, $idTypeSuivis, $idResa, $idDp, $data, $adapter);
							if ($valeur2 || $valeur2 == 0) {
								$autreValeurs[$c->id] = $valeur2;
							}
						}
					}
				}
			}

			$view = new JsonModel(array(
						'valeur' => $valeur,
						// 'valeurs' => $valeurs,
						'autreValeurs' => $autreValeurs,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Load liste options : mode réservation
	public function loadListeOptionsAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idListe = (int) $request->getPost('idListe');
			$mode = $request->getPost('mode', '');

			$allowedListe = $this->getAllowedListes($mode);
			$categoriesListes = $this->getListesTable()->getCategoriesListe($adapter, $mode);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
			->setTemplate('reservation/liste/listeoptions')
			->setVariables(array(
						   'listes'		=> $allowedListe,
						   'idListe'	=> $idListe,
						   'categoriesListes' => $categoriesListes,
			));

			$listeOptions = $this->getServiceLocator()
			->get('viewrenderer')
			->render($htmlViewPart);

			$view = new JsonModel(array(
						'listeOptions' => $listeOptions,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function getAllowedListes($mode = '')
	{
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		## Extraire la liste des listes permises : celles du profil et les privées
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$allowedListe = array();
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		if($mode == 'dp') {
			$allListes = $this->getListesTable()->fetchAllByProfile($idProfile, 'dp', $adapter);
		} else {
			$allListes = $this->getListesTable()->fetchAllByProfile($idProfile);
		}
		if ($allListes) {
			foreach ($allListes as $liste) {
				//on affiche les listes public ## AAK on ignore maintenant la notion de public
				if(!is_object($liste)) {
					$liste = (object)$liste;
				}
				$allowedListe[] = $liste;
			}
		}
		if($mode == 'dp') {
			$allListes = $this->getListesTable()->fetchAllPrivate($gestId, 'dp', $adapter);
		} else {
			$allListes = $this->getListesTable()->fetchAllPrivate($gestId);
		}

		if ($allListes) {
			foreach ($allListes as $liste) {
				if(!is_object($liste)) {
					$liste = (object)$liste;
				}
				$allowedListe[] = $liste;
			}
		}
		return $allowedListe;
	}


	## Facturation prestations suivis
	public function facturerPrestationsSuivisAction()
	{
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idsSuivis = $request->getPost('ids', array());
			$etat = $request->getPost('etat');
			$dateFacture = $request->getPost('dateFacture');
			if (!$dateFacture) {
				$dateFacture = date('d-m-Y');
			}

			$tableResa = $this->getTableObjet('reservations');

			$msgErrors = '';
			$msg = '';
			$success = false;
			$facturesGenerer = array();

			$rows = $this->getFormuleExcelTable()->getPrestationsAFacturer($idsSuivis, $etat);

			foreach ($rows as $idResa => $prestations) {
				$select = $tableResa->getSql()->select();
				$select->join('locataires', 'locataires.id = reservations.idLocataire', array('idLoc' => 'id', 'nomLocataire' => 'nom', 'prenomLocataire' => 'prenom'));
				$select->where(array('reservations.id' => $idResa));
				$row = $tableResa->selectWith($select)->current();


				if ($etat == 'facture') {
					$noFact = $this->creerPrestaFacture($idResa, 'participation', array('prestations' => $prestations, 'dateFacture' => $dateFacture));
					if (is_array($noFact)) {
						$msg .= "Erreur :resa $idResa ".implode($noFact);
					} else {
						$msg .= "Facture $noFact créée pour résa $idResa<br>";
						if ($noFact) {
							$facturesGenerer[] = array('idReservation' => $idResa, 'noFacture' => $noFact);
						}
						$success = true;
					}
					//if($noFact) $facturesGenerer[] = array('idReservation'=>$idResa,'noFacture'=>$noFact);
				} elseif ($etat == 'preparationFacture') {
					$ret = $this->creerPrestaPreparationFacture($idResa, 'participation', array(), 0, array('prestations' => $prestations));
					if (is_array($ret)) {
						$msg .= "Erreur :resa $idResa ".implode($ret);
					} else {
						$msg .= "Préparation de facture pour résa $idResa<br>";
						$success = true;
					}
				}
			}

			$urlPDF = "";
			if ($success && !empty($facturesGenerer)) {
				//generer le modele de document des factures générées
				$modele = $this->getTableObjet('type_modeles_docs')->select(array('code' => 'FACT'))->current();
				if ($modele) {
					$urlPDF = $this->genererPdfMergeDocument($facturesGenerer, $modele->id, 'facture');
				}
			}

			$view = new JsonModel(array(
						'success' => true,
						'msgErrors' => $msgErrors,
						'msg' => $msg,
						'urlPDF' => $urlPDF,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Distribution codes
	public function distribuerCodesAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		if ($request->isXmlHttpRequest()) {
			$idsResa = $request->getPost('ids', array());
			$idCampagne = $request->getPost('idCampagne', null);

			$msgErrors = $msgSuccess = "";
			$tableResa = $this->getTableObjet('reservations');
			$tableLoc = $this->getTableObjet('locataires');
			$tableProg = $this->getTableObjet('programmes');
			$i = 0;
			$now = date('Y-m-d H:i:s');

			$canalGest = $this->getProgrammeTable()->getCanalResidence();

			if ($idCampagne) {
				foreach ($idsResa as $idResa) {
					$select = $tableResa->getSql()->select();
					$select->join('locataires', 'locataires.id = reservations.idLocataire', array('idLoc' => 'id', 'nomLocataire' => 'nom', 'prenomLocataire' => 'prenom', 'idCodeLoc' => 'idCode'));
					$select->where(array('reservations.id' => $idResa));
					$resa = $tableResa->selectWith($select)->current();
					if ($resa) {
						$passer = true;
						$idProgramme = $canalGest ? $canalGest->id : $resa->idProgramme;
						if ($idProgramme) {
							if ($resa->idCodeLoc) {
								// on vérifie si le code est tjr en etat distirue
								$programme = $tableProg->select(array('id' => $idProgramme))->current();
								if ($programme) {
									$codeObj = $this->getCodeTable()->getCode($resa->idCodeLoc);
									if ($codeObj && $codeObj->idEtat == 2) {
										$dateAttribution = $codeObj->dateAttribution;
										$dureeValiditeCode = $programme->dureeValiditeCode;
										$datePlusDuree = date('d-m-Y H:i:s', strtotime($dateAttribution." + ".$dureeValiditeCode." hour"));
										if (strtotime($now) <= strtotime($datePlusDuree)) {
											$passer = false;
										}
									}
								}
							}
							$codeCanal = $this->getCodeTable()->getCodeByCanalCampagne($idProgramme, $resa->idCampagne);
							if ($codeCanal && $passer) {
								$upData = array('idEtat' => '2',
												'dateAttribution' => date('Y-m-d H:i:s'),
												'nomLocataire' => $resa->nomLocataire,
												'prenomLocataire' => $resa->prenomLocataire,
												);
								$this->getCodeTable()->updateCode($upData, $codeCanal->id);
								$tableLoc->update(array('idCode' => $codeCanal->id), array('id' => $resa->idLocataire));
								//envois mail au résident
								$this->envoyerMail($idResa, 8);
								$i++;
							} elseif ($codeCanal && !$passer) {
								$msgErrors .= "Code déjà distribuer pour ".$resa->nomLocataire." ".$resa->prenomLocataire." <br>";
							} else {
								$msgErrors .= "Code indisponible pour ".$resa->nomLocataire." ".$resa->prenomLocataire." <br>";
							}
						} else {
							$msgErrors .= "canal indisponible pour ".$resa->nomLocataire." ".$resa->prenomLocataire." <br>";
						}
					}
				}
			} else {
				$msgErrors = "Veuillez choisir une campagne";
			}
			if ($i > 0) {
				$msgSuccess = "$i codes distribués";
			}

			$view = new JsonModel(array(
						'success' => true,
						'msgErrors' => $msgErrors,
						'msgSuccess' => $msgSuccess,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	//recup tout les dossier de toutes les listes de type indicateur de différents modes
	public function getAllListesIndicateursRows()
	{
		$rowsAll = array();
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$conf = $this->getConfigurationTable()->getConfig(1);
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		$now = date('Y-m-d');

		$listesParMode = $this->getListesTable()->getAllListesIndicateurs($gestId, $idProfile, $adapter, $typeRetour = "parMode");
		foreach ($listesParMode as $mode => $listes) {
			foreach ($listes as $liste) {
				$typeListe = $liste->idTypeListe;
				$idListe = $liste->id;
				$ret = array();
				if ($mode == "resa" || $mode == "dp") {
					if ($mode == "dp") {
						$listeState = $this->loadDomiciliationsState($idListe);
					} else {
						$listeState = $this->loadResaState($idListe);
					}
					$columns = array();
					$order = array();
					$cols = !empty($listeState['filter']) ? $listeState['filter'] : array();
					$orders = !empty($listeState['order']) ? $listeState['order'] : array();
					$i = 0;
					foreach ($cols as $colName => $opts) {
						$columns[] = array('data' => $colName,
											'name' => $colName,
											'searchable' => true,
											'orderable' => true,
											'search' => array('value' => $opts['search']),
											);
					}

					foreach ($orders as $o) {
						$order[] = array('column' => $o[0], 'dir' => $o[1]);
					}
					$data = array('idListe' => $idListe,
									'columns' => $columns,
									'order' => $order,
									'start' => '0',
									'length' => '-1',
									'typeAppel' => 'modeIndicateurs',
									);
					$this->request->setMethod('POST')->setPost(new Parameters($data));
					if ($mode == "dp") {
						$ret = $this->getServerJsonDataDpAction();
					} else {
						$ret = $this->getServerJsonDataAction();
					}
				} elseif ($mode == "suivis" || $mode == "demandes") {
					$ret = $this->getServerJsonDataForward($idListe, $mode);
				}

				if (!empty($ret)) {
					$rowsData = !empty($ret['data']) ? $ret['data'] : array();
					if (!empty($rowsData)) {
						$rowsListe = array();
						foreach ($rowsData as $rowData) {
							$rowData['nomIndicateur'] = $liste->nom;
							$rowData['dureeFiltreIndicateur'] = '';
							if ($liste->configFilters && !empty($liste->configFilters)) {
								foreach ($rowData as $rowName => $rowVal) {
									if (array_key_exists($rowName, $liste->configFilters) && $rowVal) {
										$champFiltre = $liste->configFilters[$rowName];
										if ($champFiltre['type'] == 'date') {
											//on fait la diff entre cette date et la date du jour
											$dateDebut = new \DateTime($rowVal);
											$dateFin = new \DateTime($now);
											$difference = $dateDebut->diff($dateFin);
											$dureeIndicateur = $difference->format('%a');
											$rowData['dureeFiltreIndicateur'] = $dureeIndicateur;
										}
									}
								}
							}
							$rowsListe[] = $rowData;
						}
						$rowsAll = array_merge($rowsAll, $rowsListe);
					}
				}
			}
		}

		return $rowsAll;
	}

	public function getServerJsonDataForward($idListe, $mode, $ext = '')
	{
		$return = array();
		if ($mode == "suivis") {
			$return = $this->forward()->dispatch('Reservation\Controller\Multisuivis', array(
											'action' => 'getServerJsonDataForward',
											'params'	=> array('idListe' => $idListe),
							));
		} elseif ($mode == "demandes") {
			$return = $this->forward()->dispatch('Reservation\Controller\Demandes', array(
											'action' => 'getServerJsonDataForward',
											'params'	=> array('idListe' => $idListe, 'ext' => $ext),
							));
		}
		if (is_object($return)) {
			$return = $return->getVariables();
		}
		return $return;
	}

	public function scriptAjoutIntercontatAction()
	{
		$tools = new Tools();
		$idCampagne = (isset($_GET['idCampagne']) && $_GET['idCampagne'] != "") ? $_GET['idCampagne'] : null;
		$date = (isset($_GET['date']) && $_GET['date'] != "") ? $_GET['date'] : null;
		if (!$idCampagne) {
			echo "Veuillez ajouter le param ?idCampagne=xx";
			exit();
		}
		if (!$date) {
			echo "Veuillez ajouter le param ?date=yyyy-mm-dd pou determiner a partir de quelle date depart on commence";
			exit();
		}
		if (!$tools->isValideDate($date)) {
			echo "Date $date invalide";
			exit();
		}
		$etatIC = $this->getPremierEtatIC();

		$tableResa = $this->getTableObjet('reservations');
		$resas = $tableResa->select(array('etat' => 6, 'idCampagne' => $idCampagne, 'archive' => '0'));
		$i = 0;
		foreach ($resas as $resa) {
			$idResa = $resa->id;
			if (!$resa->dateDepart || substr($resa->dateDepart, 0, 2) == '00' || $resa->idIntercontrat || $resa->idNouvelleResa) {
				continue;
			}
			if (strtotime($resa->dateDepart) < strtotime($date)) {
				continue;
			}
			$upData = array();
			if ($etatIC->id > 0) {
				$upData['idIntercontrat'] = $etatIC->id;
			}
			if (!empty($upData)) {
				$this->getResaTable()->updateResa($upData, array('id' => $idResa));

				if ($etatIC->id > 0) {
					//on ajoute l intercontrat
					$this->ajouterEtatIntercontrat($idResa, $resa->dateDepart, "", null, $etatIC->id);

					//maj de l'etat de logement en intercontrat => 3
					$this->getLogementTable()->updateLogement(array('idEtat' => 3), array('id' => $resa->idLogement));
					echo "Resa $idResa : logement ".$resa->numeroChambre." passer en IC<br>";
					$i++;
				}
			}
		}
		echo "Terminer $i resa traite";
		exit();
	}

	/**
	 * Function that groups an array of associative arrays by some key.
	 *
	 * @param {String} $key Property to sort by.
	 * @param {Array} $data Array that stores multiple associative arrays.
	 */
	public function group_by($key, $data)
	{
		$result = array();

		foreach ($data as $val) {
			if (array_key_exists($key, $val)) {
				$result[$val[$key]][] = $val;
			} else {
				$result[""][] = $val;
			}
		}

		return $result;
	}

	public function getCodeTable()
	{
		if (!$this->codeTable) {
			$sm = $this->getServiceLocator();
			$this->codeTable = $sm->get('Reservation\Model\CodeTable');
		}
		return $this->codeTable;
	}

	private function getDashboardTable()
	{
		if (!$this->dashboardTable) {
			$sm = $this->getServiceLocator();
			$this->dashboardTable = $sm->get('Reservation\Model\DashboardTable');
		}
		return $this->dashboardTable;
	}

	public function getOngletsFormulairesTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->ongletsFormulairesTable) {
			$this->ongletsFormulairesTable = new OngletsFormulairesTable($adapter);
		}
		return $this->ongletsFormulairesTable;
	}

	public function getCategorieDocumentFormulaireTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->categorieDocumentFormulaireTable) {
			$this->categorieDocumentFormulaireTable = new CategorieDocumentFormulaireTable($adapter);
		}
		return $this->categorieDocumentFormulaireTable;
	}

	public function getTypeSuivisFormulaireTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->typeSuivisFormulaireTable) {
			$this->typeSuivisFormulaireTable = new TypeSuivisFormulaireTable($adapter);
		}
		return $this->typeSuivisFormulaireTable;
	}

	public function getFormuleExcelTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$sm = $this->getServiceLocator();
		if (!$this->formuleExcelTable) {
			$this->formuleExcelTable = new FormuleExcelTable($adapter, $sm);
		}
		return $this->formuleExcelTable;
	}

	public function getTableCategorieDocs()
	{
		if (!$this->categorieDocumentTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->categorieDocumentTable = new CategorieDocumentTable($adapter);
		}
		return $this->categorieDocumentTable;
	}

	public function getFinancierTable()
	{
		if (!$this->financierTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->financierTable = new FinancierTable($adapter);
		}
		return $this->financierTable;
	}

	public function getPrestationsCheckinTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if (!$this->prestationsCheckin) {
			$this->prestationsCheckin = new PrestationsCheckinTable($adapter);
		}
		return $this->prestationsCheckin;
	}

	public function getModeleEtLoyerFacture($idResa)
	{
		$return = $this->forward()->dispatch('Application\Controller\Reservation', array(
				'action' => 'getModeleEtLoyerFactureForward',
				'id'    => $idResa,
			));
		if (is_object($return)) {
			$return = $return->getVariables();
		}

		return $return;
	}


	public function getChampsCafTable()
	{
		if (!$this->champsCafTable) {
			$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
			$this->champsCafTable = new ChampsCafTable($adapter);
		}
		return $this->champsCafTable;
	}

	public function ficheusagerportailAction()
	{
		$session = new Container('reservation');
		$resa = $session->reservation;
		$idResa	= $resa ? $resa->id : 0;
		$idDp = $session->idDp ? $session->idDp : null;
		if(!$idResa && !$idDp) {
			echo utf8_decode("Aucun id dossier trouvé");
			exit();
		}

		$accessFicheUsager = false;
		if(($_SESSION['USERDROIT']['ficheclient'] == 'W' || $_SESSION['USERDROIT']['ficheclient'] == 'R')) {
			$accessFicheUsager = true;
		}
		if(!$accessFicheUsager) {
			echo utf8_decode("Vous n'avez pas accès à cette page");
			exit();
		}

		return array(
				'idResa' => $idResa,
				'idDp' => $idDp,
				'modalFicheClient' => $this->getFicheClienModal(),
				'typesSuivis' => $this->getListeTypesSuivis(),
				'typesCatalogue' => $this->getCatalogueTable()->getTypesCatalogueListe(),
				);
	}

	// Signature de documents
	public function signatureDocumentsAction()
	{
		$request = $this->getRequest();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : post=".json_encode($request->getPost()));
		if ($request->isXmlHttpRequest()) {
			$mode	= $request->getPost('mode', '');
			$from	= $request->getPost('from', '');
			$ids	= $request->getPost('ids', array());

			## Recherche de la liste des API de signature valides
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$rows	= $this->getApisignatureTable()->fetchAll();
			$apiSignatures	= [];
			if ($rows) {
				foreach ($rows as $apiSignature) {
					if ($apiSignature->active) {
						$apiSignatures[$apiSignature->id]	= $apiSignature;
					}
				}
			}
			syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] apiSignatures=".json_encode($apiSignatures));

			## Recherche des modèles de documents pour des API de signature valides
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$modeles	= [];
			if ($apiSignatures) {
				try {
					$tableModelesDocs	= $this->getTableObjet('type_modeles_docs');
					$select			= $tableModelesDocs->getSql()->select();
					$select->where(array('active' => 1, 'typeModele' => 'reservation'));
					$select->where->in('type_modeles_docs.idApiSignature', array_keys($apiSignatures));
					$modeles		= $tableModelesDocs->selectWith($select);
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : mode=$mode Exception=".$ex->getMessage());
				}
			}
			syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] modeles=".json_encode($modeles));

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/signaturedocumentsresa')
				->setVariables(array(
					'apiSignatures'	=> $apiSignatures,
					'modeles'	=> $modeles,
					'ids'		=> $ids,
					'mode'		=> $mode,
					'from'		=> $from,
				));

			$htmlOutput = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);

			$view = new JsonModel(array(
				'success' => true,
				'htmlOP' => $htmlOutput,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function lancerSignatureDocumentsAction()
	{
		## Puisque l'opération peut-être longue
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		set_time_limit(0);

		$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$confTable	= $this->getConfigurationTable();
		$conf		= $confTable->getConfig(1);
		$erreurs	= [];
		$dossiers	= [];

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : post=".json_encode($request->getPost()));
			$mode		= $request->getPost('mode', '');
			$idModele	= $request->getPost('idModele');
			$idsResa	= $request->getPost('ids');//par forcement idsResa, mais idsDp si le mode==dp

			if ($idsResa) {
				## Suppression des éventuels doublons de la liste
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$idsResa	= array_unique($idsResa);
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idsResa=".json_encode($idsResa));
			if (!$idsResa) {
				$erreurs[]	= "Pas de dossiers sélectionnés";
			}
			$nbIdsResa	= count($idsResa);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele count_idsResa=$nbIdsResa");

			if (!$erreurs) {
				$modele	= null;
				try {
					## Lecture du modèle de document
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($idModele) {
						$modele = $this->getTableObjet('type_modeles_docs')->select(array('id' => $idModele))->current();
						if (!$modele) {
							$erreurs[]	= "Impossible d'identifier idModele=$idModele";
						}
					} else {
						$erreurs[]	= "Pas de modèle sélectionné";
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele modele=".json_encode($modele));

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele Exception=".$ex->getMessage();
				}
			}

			if (!$erreurs) {
				## Lecture de l'API-Signature
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~
				$idApiSignature	= $modele->idApiSignature;
				if ($idApiSignature) {
					try {
						## Initialisation du SIGNATURE
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

						## Création du SIGNATURE Generique
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						try {
							$signatureGen	= new SignatureGen($adapter, $idApiSignature);
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage());
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage();
						}

						if (!$signatureGen) {
							## Pas de signatureGen ??
							## ~~~~~~~~~~~~~~~~~~~~~~
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Pas de signatureGen");
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Pas de signatureGen";
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureGen=".json_encode($signatureGen));

						## Connexion au SIGNATURE explicite
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						try {
							$signature	= $signatureGen->connect(Signature::TRACE_DEFAULT);
							if (is_object($signature)) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureClass=".get_class($signature));
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature ConnectErr=$signature");
								$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature connectErr=$signature";
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature connectSignature Exception=".$ex->getMessage());
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature connectSignature Exception=".$ex->getMessage();
						}

					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage());
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage();
					}

				} else {
					$erreurs[]	= "idModele=$idModele : pas de idApiSignature";
				}
			}

			if (!$erreurs) {
				## Tout est prêt pour générer les documents et puis les signer
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				foreach ($idsResa as $idResa) {
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

					## Lecture des infos du locataire
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$resa =  $this->getResaTable()->getResa($idResa);
					if (!$resa) {
						syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa : resa absente");
						$erreurs[]	= "idModele=$idModele idResa=$idResa : resa absente !!";
						continue;
					}
					$idLocataire	= $resa->idLocataire;
					syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa idLocataire=$idLocataire resa=".json_encode($resa));
					$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $idResa);
					syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa idLocataire=$idLocataire loc=".json_encode($loc));

					## Vérification de l'état de signature du document
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$docResa	= null;
					try {
						$docsResa	= $this->getDocumentTable()->getAllDocumentByReservation($idResa);
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa nbRows=".$docsResa->count());
						if ($docsResa) {
							foreach ($docsResa as $doc) {
								syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa doc=".json_encode($doc));
								if ($doc->idTypeDocument == $idModele && $doc->signState > 0) {
									$docResa	= $doc;
									break;
								}
							}
						}
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa docResa=".json_encode($docResa));
					} catch (\Exception $ex) {
						syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa getAllDocumentByReservation Exception=".$ex->getMessage());
						$erreurs[]	= "idModele=$idModele idResa=$idResa getAllDocumentByReservation Exception=".$ex->getMessage();
						continue;
					}

					if ($docResa) {
						## Un contrat est déjà créé
						## ~~~~~~~~~~~~~~~~~~~~~~~~
						if ($docResa->signState == 4) {
							$dossiers[$idResa]['err']	= "Déjà signé";
						} else {
							$dossiers[$idResa]['err']	= "En cours de signature";
						}
						continue;
					}

					## Recherche de la résidence
					## ~~~~~~~~~~~~~~~~~~~~~~~~~
					$idResidence	= 0;
					if ($resa->idLogement) {
						$residence = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
						if ($residence) {
							$idResidence	= $residence->idResidence;
						}
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa idResidence=$idResidence");

					## Recherche des paramètres de la signature pour ce modèle et cette résidence
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$paramModeleDoc	= null;
					$nbSignataires	= 0;
					try {
						if ($idResidence) {
							## Paramètres de la signature pour cette résidence
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$paramModeleDoc = $this->getTableObjet('api_signature_modeles_docs')->select(array('idModeleDoc' => $idModele, 'idApiSignature' => $idApiSignature, 'idResidence' => $idResidence))->current();
						}
						if (!$paramModeleDoc) {
							## Paramètres de la signature ggénérique pour ce modèle
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$paramModeleDoc = $this->getTableObjet('api_signature_modeles_docs')->select(array('idModeleDoc' => $idModele, 'idApiSignature' => $idApiSignature, 'idResidence' => 0))->current();
						}
						if ($paramModeleDoc) {
							## Transformation de la liste des signataires et de la description du cachet en tableau PHP
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							if ($paramModeleDoc['signataires']) {
								$signataires	= json_decode($paramModeleDoc['signataires'], 1);
								if ($signataires === null) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa : erreur de décodage du champ 'signataire' de paramModeleDoc=".json_encode($paramModeleDoc));
									$erreurs[]	= "Erreur de décodage du champ 'signataires' pour idResa=$idResa idModele=$idModele";
								}
								$paramModeleDoc['signataires']	= $signataires;
							}
							if (!$signataires || ($nbSignataires = count($signataires)) == 0) {
								$erreurs[]	= "Le champ 'signataires' ne doit pas être vide pour idResa=$idResa idModele=$idModele";
							}
							if ($paramModeleDoc['cachet']) {
								$cachet	= json_decode($paramModeleDoc['cachet'], 1);
								if ($cachet === null) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa : erreur de décodage du champ 'cachet' de paramModeleDoc=".json_encode($paramModeleDoc));
									$erreurs[]	= "Erreur de décodage du champ 'cachet' pour idResa=$idResa idModele=$idModele";
								}
								$paramModeleDoc['cachet']	= $cachet;
							}
							if ($paramModeleDoc['avecCachet']) {
								if (!$paramModeleDoc['cachet']) {
									$erreurs[]	= "Le champ 'cachet' ne doit pas être vide pour idResa=$idResa idModele=$idModele";
								}
							}

						} else {
							$erreurs[]	= "Impossible d'identifier les paramètres de signature pour idResa=$idResa idModele=$idModele";
						}
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa idResidence=$idResidence : paramModeleDoc=".json_encode($paramModeleDoc));

					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignatur$idApiSignature getParamModeleDoc Exception=".$ex->getMessage());
						$erreurs[]	= " idModele=$idModele idApiSignatur$idApiSignature getParamModeleDoc Exception=".$ex->getMessage();
					}

					if (1 && $paramModeleDoc && $nbSignataires > 0) {
						$returnUrl	= null;
						$docId		= null;
						$youSignDocId	= null;
						try {
							## Génération du document .pdf de contrat personnalisé
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => false, 'avecSignature' => true);
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa avant genererModeleDocument");
							$returnUrl = $this->genererModeleDocument($idResa, "", $idModele, $options);
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa pour $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl");
							if (file_exists($returnUrl)) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument returnUrl=$returnUrl : file exists");
								$dossiers[]	= "$loc[nom] $loc[prenom] ($loc[email]) : document généré";
							} else {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument pour $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl : file doesnt exist");
								$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa genererModeleDocument pour $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl illisible. Relancer la generation";
								$returnUrl	= null;
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage());
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage();
						}
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature returnUrl=$returnUrl");
						try {
							if ($returnUrl && is_string($returnUrl)) {

								## Insertion du document .pdf dans la table des documents
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$doc			= new Document();
								$doc->nom		= basename($returnUrl);
								$doc->idTypeDocument	= $idModele;
								$doc->langue		= "fr_FR";
								$doc->signIdApi		= null;
								$doc->signDocId		= null;
								$doc->signState		= null;
								$docId			= $this->getDocumentTable()->saveDocument($doc);

								## Insertion du lien entre document et locataire
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$this->getDocumentLocataireTable()->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
							}
						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage());
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage();
							continue;
						}
					}

					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature docId=$docId");
					if (1 && $docId) {
						$fileNameAsigner	= $returnUrl;

						## Lancement de la signature en fonction de la classe de signature
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$signatureClassName	= $signature->getClassName();
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureClassName=$signatureClassName");
						if ($signatureClassName == 'DocuSign') {
							## =======================================================================
							## Signature par DocuSign
							## =======================================================================
							try {
								$result	= $this->signerDocuSign($signature, $idResa, $loc, $fileNameAsigner, $paramModeleDoc, $docId);
								syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa result=".json_encode($result));
								if ($result['erreurs']) {
									array_push($erreurs, $result['erreurs']);
								}
								if ($result['dossiers']) {
									array_push($dossiers, $result['dossiers']);
								}
							} catch (\Exception $ex) {
								syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature fileNameAsigner=$fileNameAsigner=$fileNameAsigner signerDocuSign Exception=".$ex->getMessage());
								$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId signerDocuSign Exception=".$ex->getMessage();
								continue;
							}

						} elseif ($signatureClassName == 'YouSign') {
							## =======================================================================
							## Signature par YouSign
							## =======================================================================

							## Chargement d'un document pour scellement
							## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
							$youSignFileName	= $returnUrl;
							if ($paramModeleDoc['avecCachet']) {
								try {
									$params	= [
										'fileName'		=> $youSignFileName,
										];
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadSealDocument params=".json_encode($params));
									$resultUploadSealDocument = $signature->uploadSealDocument($params);
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadSealDocument resultUploadSealDocument=".json_encode($resultUploadSealDocument));
									$idSealDocument	= $resultUploadSealDocument['idSealDocument'];
								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature uploadSealDocument Exception=".$ex->getMessage());
									$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadSealDocument Exception=".$ex->getMessage();
									continue;
								}

								if (1 && $docId && $idSealDocument) {
									## Ajouter un cachet d'entreprise
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									try {
										$params	= [
											'docId'		=> $idSealDocument,
											'idResidence'	=> $idResidence,
											'paramModeleDoc' => $paramModeleDoc,
											];
										syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal params=".json_encode($params));
										$electronicSealResult	= $signature->electronicSeal($params);
										if ($electronicSealResult && $electronicSealResult['sealId']) {
											syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal OK: electronicSealResult=".json_encode($electronicSealResult));
											$electronicSealId	= $electronicSealResult['sealId'];
										} else {
											syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal ERR: electronicSealResult=".json_encode($electronicSealResult));
											$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId electronicSeal ERR=".json_encode($electronicSealResult);
											continue;
										}

									} catch (\Exception $ex) {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature electronicSeal Exception=".$ex->getMessage());
										$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId electronicSeal Exception=".$ex->getMessage();
										continue;
									}
								}

								$electronicSealStatus	= null;
								if (1 && $docId && $idSealDocument && $electronicSealId) {
									## Boucle de lecture de l'état du cachet jusqu'à ce qu'il soit bon
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									try {
										$ind	= 0;
										while ($electronicSealStatus != 'done' && $ind < 20) {
											$params	= [
												'electronicSealId'	=> $electronicSealId,
												];
											syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal params=".json_encode($params));
											$electronicSealResult	= $signature->getElectronicSeal($params);
											if ($electronicSealResult) {
												syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa getElectronicSeal OK: electronicSealResult=".json_encode($electronicSealResult));
												$electronicSealStatus	= $electronicSealResult['status'];
												$ind++;
												sleep(2);
											} else {
												syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa getElectronicSeal ERR: electronicSealResult=".json_encode($electronicSealResult));
												$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId getElectronicSeal ERR=".json_encode($electronicSealResult);
												break;
											}
										}

									} catch (\Exception $ex) {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature getElectronicSeal Exception=".$ex->getMessage());
										$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId getElectronicSeal Exception=".$ex->getMessage();
										continue;
									}

								}
								$youSignSealFileName	= null;
								if (1 && $docId && $idSealDocument && $electronicSealId && $electronicSealStatus == 'done' && $youSignFileName) {
									## Identifier le path du fichier actuel
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									$pathParts	= pathinfo($youSignFileName);
									$extension	= $pathParts['extension'];
									$filename	= $pathParts['filename'];
									$youSignSealFileName	= getcwd()."/public/docs/locataires/$idLocataire/uploads/contratsSignes/".$filename."_SEAL.".$extension;

									## Téléchargement du fichier scellé
									## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
									try {
										$params	= [
											'idApiSignature'		=> $idApiSignature,
											'electronicSealDocumentId'	=> $idSealDocument,
											'filePathName'			=> $youSignSealFileName,
											];
										$result	= $signature->downloadSealDocument($params);
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature  electronicSealDocumentId=$idSealDocument result=".json_encode($result));
										if (file_exists($youSignSealFileName)) {
											$dossiers[]	= "$loc[nom] $loc[prenom] ($loc[email]) : document cacheté";
										}
									} catch (\Exception $ex) {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature downloadSealDocument Exception=".$ex->getMessage());
										$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId downloadSealDocument Exception=".$ex->getMessage();
									}
								}
							} else {
								$youSignSealFileName	= $youSignFileName;
								$dossiers[]		= "$loc[nom] $loc[prenom] ($loc[email]) : document non cacheté avant de signer";
							}

							#syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature electronicSeal : fin provisoire");
							#continue;

							$idSignatureRequest	= null;
							if (1 && $docId && file_exists($youSignSealFileName)) {

								## Lancement de la requête de signature
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								try {
									$params	= [
										'requestName'		=> $paramModeleDoc['nomRequete'] ? sprintf($paramModeleDoc['nomRequete'], $loc['prenom'], $loc['nom']) : "Document à signer pour $loc[prenom] $loc[nom]",
										'paramModeleDoc'	=> $paramModeleDoc,
										];
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa signatureRequest params=".json_encode($params));
									$idSignatureRequest = $signature->signatureRequest($params);
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa signatureRequest idSignatureRequest=$idSignatureRequest");
								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureRequest Exception=".$ex->getMessage());
									$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId signatureRequest Exception=".$ex->getMessage();
									continue;
								}
							}

							if (1 && $docId && $idSignatureRequest && file_exists($youSignSealFileName)) {
								sleep(2);
								$youSignFileName	= $returnUrl;

								## Upload du document à signer
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
								try {
									$params	= [
										'idSignatureRequest'	=> $idSignatureRequest,
										'fileName'		=> $youSignSealFileName,
										'paramModeleDoc'	=> $paramModeleDoc,
										'avecParaphe'		=> $paramModeleDoc['avecParaphes'],
										];
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument params=".json_encode($params));
									$uploadResult	= $signature->uploadDocument($params);
									if ($uploadResult && $uploadResult['idDocument']) {
										syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument OK: uploadResult=".json_encode($uploadResult));
										$youSignDocId	= $uploadResult['idDocument'];
									} else {
										syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument ERR: uploadResult=".json_encode($uploadResult));
										$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadDocument ERR=".json_encode($uploadResult);
										continue;
									}

								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature uploadDocument Exception=".$ex->getMessage());
									$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadDocument Exception=".$ex->getMessage();
									continue;
								}
							}

							if (1 && $docId && $idSignatureRequest && $youSignDocId) {
								sleep(2);

								## Mémorisation de l'identifiant de demande de signature
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$data	= [ 'signIdApi' => $idApiSignature, 'signIdRequest' => $idSignatureRequest, 'signDocId' => $youSignDocId, 'signState' => 101];
								$this->getDocumentTable()-> updateDocument($docId, $data);
							}

							if (1 && $docId && $idSignatureRequest && $youSignDocId) {
								sleep(2);

								## Ajout du signataire 1
								## ~~~~~~~~~~~~~~~~~~~~~
								foreach ($paramModeleDoc['signataires'] as $indSigner => $paramSigner) {
									if ($paramSigner['fixedSigner']) {
										$signerEmail		= $paramSigner['email'];
										$signerFirstName	= $paramSigner['first_name'];
										$signerLastName		= $paramSigner['last_name'];
										$signerLocale		= $paramSigner['locale'];
									} else {
										$signerEmail		= $loc[$paramSigner['email']];
										$signerFirstName	= $loc[$paramSigner['first_name']];
										$signerLastName		= $loc[$paramSigner['last_name']];
										$signerLocale		= $loc[$paramSigner['locale']] == 'EN' ? 'en' : 'fr';
									}
									if ($signerEmail && $signerFirstName && $signerLastName) {
										try {
											$params	= [
												'idSignatureRequest'	=> $idSignatureRequest,
												'signerEmail'		=> $signerEmail,
												'signerFirstName'	=> $signerFirstName,
												'signerLastName'	=> $signerLastName,
												'signerLocale'		=> $signerLocale,
												];
											syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$ind params=".json_encode($params));
											$addSignerResult	= $signature->addSigner($params);
											if ($addSignerResult && $addSignerResult['idSigner']) {
												syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$ind OK: addSignerResult=".json_encode($addSignerResult));
												$youSignSignerId	= $addSignerResult['idSigner'];
											} else {
												syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$ind ERR: addSignerResult=".json_encode($addSignerResult));
												$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner$ind ERR=".json_encode($addSignerResult);
												continue;
											}

										} catch (\Exception $ex) {
											syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner$ind Exception=".$ex->getMessage());
											$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner$ind Exception=".$ex->getMessage();
											continue;
										}
									} else {
										syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner$ind : email=$signerEmail firstName=$signerFirstName lastName=$signerLastName : ignorer");

									}
								}
							}

							if (1 && $docId && $idSignatureRequest && $youSignDocId) {
								sleep(2);

								## activation des signatures
								## ~~~~~~~~~~~~~~~~~~~~~~~~~
								try {
									$params	= [
										'idSignatureRequest'	=> $idSignatureRequest,
										];
									syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignature params=".json_encode($params));
									$activateResult	= $signature->activateSignatureRequest($params);
									if ($activateResult && $activateResult['idSignatureRequest']) {
										syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignatureRequest OK: activateResult=".json_encode($activateResult));
										$dossiers[]	= "$loc[nom] $loc[prenom] ($loc[email]) : signatures demandées";
									} else {
										syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignatureRequest ERR: activateResult=".json_encode($activateResult));
										$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId activateSignatureRequest ERR=".json_encode($activateResult);
										continue;
									}

								} catch (\Exception $ex) {
									syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner Exception=".$ex->getMessage());
									$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner Exception=".$ex->getMessage();
									continue;
								}
							}
							if (1 && $docId && $idSignatureRequest && $youSignDocId) {
								## Mémorisation de l'identifiant de demande de signature
								## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
								$data	= [ 'signState' => 102];
								$this->getDocumentTable()-> updateDocument($docId, $data);
							}
							if ($nbIdsResa > 2) {
								## Bidouille AAK pour éviter les API rate limit
								sleep(60);
								## Bidouille AAK pour éviter les API rate limit
							}
						} else {
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId signatureClassName =$signatureClassName inconnue";
						}

					}
				} // foreach idsResa

				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : nbContrats=$nbContrats");

			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idsResa=".json_encode($idsResa)." : pas de document à générer et signer");
			}

			$viewArr = array(
				'success'		=> true,
				'erreurs'		=> $erreurs,
				'dossiers'		=> $dossiers,
			);
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idsResa=".json_encode($idsResa)." : viewArr=".json_encode($viewArr));
			$view = new JsonModel($viewArr);

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	private function signerDocuSign($signature, $idResa, $loc, $fileNameAsigner, $paramModeleDoc, $docId)
	{
		$idApiSignature	= $signature->getIdApiSignature();
		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSignature=$idApiSignature idResa=$idResa fileNameAsigner=$fileNameAsigner docId=$docId paramModeleDoc=".json_encode($paramModeleDoc));
		if (!$idResa || !$loc || !$fileNameAsigner || !$paramModeleDoc || !$docId) {
			throw new \Exception(__FUNCTION__.".".__LINE__." fileNameAsigner, paramModeleDoc et docId sont obligatoires");
		}

		$erreurs	= [];
		$dossiers	= [];

		## Création du champ documents
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$docs		= [];
		$doc1Content	= null;
		$documentId	= 1;
		try {
			$doc1Content	= file_get_contents($fileNameAsigner);
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSignature=$idApiSignature idResa=$idResa fileNameAsigner=$fileNameAsigner  file_get_contents Exception=".$ex->getMessage());
		}
		if ($doc1Content) {
			$doc1	= (object) array(
				'documentId'	=> $documentId,
				'fileExtension'	=> 'pdf',
				'name'		=> 'Mon fichier à signer',
				'documentBase64'	=> base64_encode($doc1Content));
			$docs[]	= $doc1;
		}

		## Création du champ Seals
		## ~~~~~~~~~~~~~~~~~~~~~~~
		$seals		= [];
		if ($paramModeleDoc['avecCachet']) {
			$seals[]	= $paramModeleDoc['cachet'];
		}

		## Création du champ signataires
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$signers	= [];
		foreach ($paramModeleDoc['signataires'] as $indSigner => $paramSigner) {
			if ($paramSigner['fixedSigner']) {
				$signerEmail		= $paramSigner['email'];
				$signerFirstName	= $paramSigner['first_name'];
				$signerLastName		= $paramSigner['last_name'];
				$signerLocale		= $paramSigner['locale'];
			} else {
				$signerEmail		= $loc[$paramSigner['email']];
				if (empty($signerEmail) && ($paramSigner['email'] == 'emailHec')) {
					$signerEmail		= $loc['email'];
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idApiSignature=$idApiSignature idResa=$idResa emailHec vide : forcerSignerEmail=$signerEmail");
				}
				$signerFirstName	= $loc[$paramSigner['first_name']];
				$signerLastName		= $loc[$paramSigner['last_name']];
				$signerLocale		= $loc[$paramSigner['locale']] == 'FR' ? 'fr' : 'en';
			}
			$signerTabs		= $paramSigner['tabs'];
			if ($signerEmail && $signerFirstName && $signerLastName && $signerTabs) {
				$signers[]	= (object) array(
					'email'		=> $signerEmail,
					'firstName'	=> $signerFirstName,
					'lastName'	=> $signerLastName,
					'fullName'	=> "$signerFirstName $signerLastName",
					'name'		=> "$signerFirstName $signerLastName",
					'recipientId'	=> $paramSigner['recipientId'],
					'routingOrder'	=> $paramSigner['routingOrder'],
					'tabs'		=> $signerTabs,
					##'emailNotification' => (object) array( 'supportedLanguage' => 'en' ),
					);
			}
		}

		## Création du champ CarbonCopies
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		$carbonCopies	= [];
		if (0) {
			$carbonCopies[]	= (object) array(
				'recipientId'	=> "91",
				'routingOrder'	=> '2',
				'email'		=> 'akrempf@gmail.com',
				'name'		=> 'Copie AK',
			);
		}

		$recipients	= (object) array(
			'signers'	=> $signers,
			'carbonCopies'	=> $carbonCopies,
			'seals'		=> $seals,
		);

		## Création de l'enveloppe
		## ~~~~~~~~~~~~~~~~~~~~~~~
		$envelopeId	= null;
		$envelope	= (object) array(
			'emailSubject'	=> ($paramModeleDoc['nomRequete'] ? sprintf($paramModeleDoc['nomRequete'], $loc['prenom'], $loc['nom']) : "Document à signer pour $loc[prenom] $loc[nom]") . " (".date('d/m H:i').")",
			#'emailSettings'	=> (object) ['bccEmailAddress' => 'akrempf@gmail.com', 'replyEmailAddressOverride' => 'noreply@wheb.fr', 'replyEmailNameOverride' => 'HEC-TEST'],
			'documents'	=> $docs,
			'recipients'	=> $recipients,
			'status'	=> 'sent');

		try {
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa envelope: emailSubject=\"".$envelope->emailSubject."\" nbDocs=".count($envelope->documents)." recipients=".json_encode($envelope->recipients)." status=".$envelope->status);
			$result = $signature->createEnvelope($idResa, $envelope);
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa createEnvelope result=".json_encode($result));
			$envelopeId	= $result['envelopeId'];
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa createEnvelope envelopeId=$envelopeId");
			if ($envelopeId) {
				$dossiers[]	= "$loc[nom] $loc[prenom] ($loc[email]) : signatures demandées";
			} else {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa createEnvelope envelopeId=$envelopeId vide");
				$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId createEnvelope envelopeId vide";
			}
		} catch (\Exception $ex) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature createEnvelope Exception=".$ex->getMessage());
			$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId createEnvelope Exception=".$ex->getMessage();
		}

		if ($docId && $envelopeId && $documentId) {
			## Mémorisation de l'identifiant de l'enveloppe
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$data	= [ 'signIdApi' => $idApiSignature, 'signIdRequest' => $envelopeId, 'signDocId' => $documentId, 'signState' => 102];
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature updateDocument : docId=$docId envelopeId=$envelopeId documentId=$documentId");
			$this->getDocumentTable()-> updateDocument($docId, $data);
		} else {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature updateDocument erreur : docId=$docId envelopeId=$envelopeId documentId=$documentId");
		}

		syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : dossiers=".json_encode($dossiers)." erreurs=".json_encode($erreurs));
		return array('erreurs' => $erreurs, 'dossiers' => $dossiers);
	}

	public function lancerSignatureDocumentResa($params)
	{
		## Puisque l'opération peut-être longue
		## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		set_time_limit(0);

		$adapter	= $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$confTable	= $this->getConfigurationTable();
		$conf		= $confTable->getConfig(1);
		$erreurs	= [];

		## Extraction des paramètres
		## ~~~~~~~~~~~~~~~~~~~~~~~~~
		$idResa		= $params['idResa'];
		$codeModele	= $params['codeModele'];
		$idModele	= 0;
		if (!$idResa || !$codeModele) {
			throw new \Exception(__FUNCTION__.".".__LINE__." idResa=$idResa et codeModele=$codeModele sont obligatoires");
		}

		if (!$erreurs) {
			$modele	= null;
			try {
				## Lecture du modèle de document
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$modele = $this->getTableObjet('type_modeles_docs')->select(array('type_modeles_docs.code' => $codeModele))->current();
				if (!$modele) {
					$erreurs[]	= "Impossible d'identifier codeModele=$codeModele";
				} else {
					$idModele	= $modele->id;
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : codeModele=$codeModele idModele=$idModele modele=".json_encode($modele));

			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : codeModele=$codeModele Exception=".$ex->getMessage());
				$erreurs[]	= "codeModele=$codeModele Exception=".$ex->getMessage();
			}
		}

		if (!$erreurs) {
			## Lecture de l'API-Signature
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~
			$idApiSignature	= $modele->idApiSignature;
			if ($idApiSignature) {
				try {
					## Initialisation du SIGNATURE
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
					## Création du SIGNATURE Generique
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					try {
						$signatureGen	= new SignatureGen($adapter, $idApiSignature);
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage());
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage();
					}

					if (!$signatureGen) {
						## Pas de signatureGen ??
						## ~~~~~~~~~~~~~~~~~~~~~~
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Pas de signatureGen");
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Pas de signatureGen";
					}
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureGen=".json_encode($signatureGen));

					## Connexion au SIGNATURE explicite
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					try {
						$signature	= $signatureGen->connect(Signature::TRACE_DEFAULT);
						if (is_object($signature)) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureClass=".get_class($signature));
						} else {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature ConnectErr=$signature");
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature connectErr=$signature";
						}
					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature connectSignature Exception=".$ex->getMessage());
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature connectSignature Exception=".$ex->getMessage();
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature Exception=".$ex->getMessage();
				}

			} else {
				$erreurs[]	= "idModele=$idModele : pas de idApiSignature";
			}
		}

		if (!$erreurs) {
			## Tout est prêt pour générer le document et puis le signer
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa");

			## Lecture des infos du locataire
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$resa =  $this->getResaTable()->getResa($idResa);
			if (!$resa) {
				syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa : resa absente");
				$erreurs[]	= "idModele=$idModele idResa=$idResa : resa absente !!";
			}
		}
		if (!$erreurs) {
			$idLocataire	= $resa->idLocataire;
			syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa idLocataire=$idLocataire resa=".json_encode($resa));
			$loc = $this->getLocatairesTable()->getAllInfos($idLocataire, $adapter, false, $idResa);
			syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa idLocataire=$idLocataire loc=".json_encode($loc));

			## Vérification de l'état de signature du document
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$docResa	= null;
			try {
				$docsResa	= $this->getDocumentTable()->getAllDocumentByReservation($idResa);
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa nbRows=".$docsResa->count());
				if ($docsResa) {
					foreach ($docsResa as $doc) {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa doc=".json_encode($doc));
						if ($doc->idTypeDocument == $idModele && $doc->signState > 0) {
							$docResa	= $doc;
							break;
						}
					}
				}
				syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa docResa=".json_encode($docResa));
			} catch (\Exception $ex) {
				syslog(LOG_ERR, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa getAllDocumentByReservation Exception=".$ex->getMessage());
				$erreurs[]	= "idModele=$idModele idResa=$idResa getAllDocumentByReservation Exception=".$ex->getMessage();
			}
		}

		if (!$erreurs) {
			if ($docResa) {
				## Un contrat est déjà créé
				## ~~~~~~~~~~~~~~~~~~~~~~~~
				if ($docResa->signState == 4) {
					$erreurs[]	= "Déjà signé";
				} else {
					$erreurs[]	= "En cours de signature";
				}
			}
		}

		if (!$erreurs) {
			## Recherche de la résidence
			## ~~~~~~~~~~~~~~~~~~~~~~~~~
			$idResidence	= 0;
			if ($resa->idLogement) {
				$residence = $this->getLogementTable()->getResidenceDeLogement($resa->idLogement);
				if ($residence) {
					$idResidence	= $residence->idResidence;
				}
			}
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa idResidence=$idResidence");

			## Recherche des paramètres de la signature pour ce modèle et cette résidence
			## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			$paramModeleDoc	= null;
			$nbSignataires	= 0;
			try {
				if ($idResidence) {
					## Paramètres de la signature pour cette résidence
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$paramModeleDoc = $this->getTableObjet('api_signature_modeles_docs')->select(array('idModeleDoc' => $idModele, 'idApiSignature' => $idApiSignature, 'idResidence' => $idResidence))->current();
				}
				if (!$paramModeleDoc) {
					## Paramètres de la signature ggénérique pour ce modèle
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$paramModeleDoc = $this->getTableObjet('api_signature_modeles_docs')->select(array('idModeleDoc' => $idModele, 'idApiSignature' => $idApiSignature, 'idResidence' => 0))->current();
				}
				if ($paramModeleDoc) {
					## Transformation de la liste des signataires et de la description du cachet en tableau PHP
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					if ($paramModeleDoc['signataires']) {
						$signataires	= json_decode($paramModeleDoc['signataires'], 1);
						if ($signataires === null) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa : erreur de décodage du champ 'signataire' de paramModeleDoc=".json_encode($paramModeleDoc));
							$erreurs[]	= "Erreur de décodage du champ 'signataires' pour idResa=$idResa idModele=$idModele";
						}
						$paramModeleDoc['signataires']	= $signataires;
					}
					if (!$signataires || ($nbSignataires = count($signataires)) == 0) {
						$erreurs[]	= "Le champ 'signataires' ne doit pas être vide pour idResa=$idResa idModele=$idModele";
					}
					if ($paramModeleDoc['cachet']) {
						$cachet	= json_decode($paramModeleDoc['cachet'], 1);
						if ($cachet === null) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa : erreur de décodage du champ 'cachet' de paramModeleDoc=".json_encode($paramModeleDoc));
							$erreurs[]	= "Erreur de décodage du champ 'cachet' pour idResa=$idResa idModele=$idModele";
						}
						$paramModeleDoc['cachet']	= $cachet;
					}
					if ($paramModeleDoc['avecCachet']) {
						if (!$paramModeleDoc['cachet']) {
							$erreurs[]	= "Le champ 'cachet' ne doit pas être vide pour idResa=$idResa idModele=$idModele";
						}
					}

				} else {
					$erreurs[]	= "Impossible d'identifier les paramètres de signature pour idResa=$idResa idModele=$idModele";
				}
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa idResidence=$idResidence : paramModeleDoc=".json_encode($paramModeleDoc));

			} catch (\Exception $ex) {
				syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignatur$idApiSignature getParamModeleDoc Exception=".$ex->getMessage());
				$erreurs[]	= " idModele=$idModele idApiSignatur$idApiSignature getParamModeleDoc Exception=".$ex->getMessage();
			}

			if (1 && $paramModeleDoc && $nbSignataires > 0) {
				$returnUrl	= null;
				$docId		= null;
				$youSignDocId	= null;
				try {
					## Génération du document .pdf de contrat personnalisé
					## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					$options = array('urlReturn' => 'ABSOLU', 'impressionEnLot' => false, 'avecSignature' => true);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa avant genererModeleDocument");
					$returnUrl = $this->genererModeleDocument($idResa, "", $idModele, $options);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idResa=$idResa : $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl");
					if (file_exists($returnUrl)) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument returnUrl=$returnUrl : file exists");
					} else {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument pour $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl : file doesnt exist");
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa genererModeleDocument pour $loc[nom] $loc[prenom] $loc[email] returnUrl=$returnUrl illisible. Relancer la generation";

					}
					$dossiers[$idResa]['returnUrl']	= $returnUrl;
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			if (1) {
				try {
					if ($returnUrl && is_string($returnUrl)) {
						## Insertion du document .pdf dans la table des documents
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$doc			= new Document();
						$doc->nom		= basename($returnUrl);
						$doc->idTypeDocument	= $idModele;
						$doc->langue		= "fr_FR";
						$doc->signIdApi		= null;
						$doc->signDocId		= null;
						$doc->signState		= null;
						$docId			= $this->getDocumentTable()->saveDocument($doc);

						## Insertion du lien entre document et locataire
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$this->getDocumentLocataireTable()->insert(array('idDocument' => $docId, 'idReservation' => $idResa));
					}
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature genererModeleDocument Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			if (1 && $docId) {
				## Chargement d'un document pour scellement
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$youSignFileName	= $returnUrl;

				try {
					$params	= [
						'fileName'		=> $youSignFileName,
						];
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadSealDocument params=".json_encode($params));
					$resultUploadSealDocument = $signature->uploadSealDocument($params);
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadSealDocument resultUploadSealDocument=".json_encode($resultUploadSealDocument));
					$idSealDocument	= $resultUploadSealDocument['idSealDocument'];
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature uploadSealDocument Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadSealDocument Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			if (1 && $docId && $idSealDocument) {

				## Ajouter un cachet d'entreprise
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$params	= [
						'docId'		=> $idSealDocument,
						'idResidence'	=> $idResidence,
						'paramModeleDoc' => $paramModeleDoc,
						];
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal params=".json_encode($params));
					$electronicSealResult	= $signature->electronicSeal($params);
					if ($electronicSealResult && $electronicSealResult['sealId']) {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal OK: electronicSealResult=".json_encode($electronicSealResult));
						$electronicSealId	= $electronicSealResult['sealId'];
					} else {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal ERR: electronicSealResult=".json_encode($electronicSealResult));
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId electronicSeal ERR=".json_encode($electronicSealResult);
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature electronicSeal Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId electronicSeal Exception=".$ex->getMessage();
				}
			}
		}

		$electronicSealStatus	= null;
		if (!$erreurs) {
			if (1 && $docId && $idSealDocument && $electronicSealId) {
				## Boucle de lecture de l'état du cachet jusqu'à ce qu'il soit bon
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$ind	= 0;
					while ($electronicSealStatus != 'done' && $ind < 20) {
						$params	= [
							'electronicSealId'	=> $electronicSealId,
							];
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa electronicSeal params=".json_encode($params));
						$electronicSealResult	= $signature->getElectronicSeal($params);
						if ($electronicSealResult) {
							syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa getElectronicSeal OK: electronicSealResult=".json_encode($electronicSealResult));
							$electronicSealStatus	= $electronicSealResult['status'];
							$ind++;
							sleep(5);
						} else {
							syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa getElectronicSeal ERR: electronicSealResult=".json_encode($electronicSealResult));
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId getElectronicSeal ERR=".json_encode($electronicSealResult);
							break;
						}
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature getElectronicSeal Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId getElectronicSeal Exception=".$ex->getMessage();
				}

			}
		}
		$youSignSealFileName	= null;
		if (!$erreurs) {
			if (1 && $docId && $idSealDocument && $electronicSealId && $electronicSealStatus == 'done' && $youSignFileName) {
				## Identifier le path du fichier actuel
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$pathParts	= pathinfo($youSignFileName);
				$extension	= $pathParts['extension'];
				$filename	= $pathParts['filename'];
				$youSignSealFileName	= getcwd()."/public/docs/locataires/$idLocataire/uploads/contratsSignes/".$filename."_SEAL.".$extension;

				## Téléchargement du fichier scellé
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$params	= [
						'idApiSignature'		=> $idApiSignature,
						'electronicSealDocumentId'	=> $idSealDocument,
						'filePathName'			=> $youSignSealFileName,
						];
					$result	= $signature->downloadSealDocument($params);
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature  electronicSealDocumentId=$idSealDocument result=".json_encode($result));
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature downloadSealDocument Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId downloadSealDocument Exception=".$ex->getMessage();
				}
			}
		}

		$idSignatureRequest	= null;
		if (!$erreurs) {
			if (1 && $docId && file_exists($youSignSealFileName)) {
				## Lancement de la requête de signature
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$params	= [
						'requestName'	=> $paramModeleDoc['nomRequete'] ? sprintf($paramModeleDoc['nomRequete'], $loc['prenom'], $loc['nom']) : "Document à signer pour $loc[prenom] $loc[nom]",
						'paramModeleDoc' => $paramModeleDoc,
						];
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa signatureRequest params=".json_encode($params));
					$idSignatureRequest = $signature->signatureRequest($params);
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa signatureRequest idSignatureRequest=$idSignatureRequest");
				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature signatureRequest Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId signatureRequest Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			if (1 && $docId && $idSignatureRequest && file_exists($youSignSealFileName)) {
				sleep(2);

				## Upload du document à signer
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$params	= [
						'idSignatureRequest'	=> $idSignatureRequest,
						'fileName'		=> $youSignSealFileName,
						'paramModeleDoc'	=> $paramModeleDoc,
						'avecParaphe'           => $paramModeleDoc['avecParaphes'],
						];
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument params=".json_encode($params));
					$uploadResult	= $signature->uploadDocument($params);
					if ($uploadResult && $uploadResult['idDocument']) {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument OK: uploadResult=".json_encode($uploadResult));
						$youSignDocId	= $uploadResult['idDocument'];
					} else {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa uploadDocument ERR: uploadResult=".json_encode($uploadResult));
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadDocument ERR=".json_encode($uploadResult);
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature uploadDocument Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId uploadDocument Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			if (1 && $docId && $idSignatureRequest && $youSignDocId) {
				## Mémorisation de l'identifiant de demande de signature
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$data	= [ 'signIdApi' => $idApiSignature, 'signIdRequest' => $idSignatureRequest, 'signDocId' => $youSignDocId, 'signState' => 101];
				$this->getDocumentTable()-> updateDocument($docId, $data);
			}
		}

		if (!$erreurs) {
			if (1 && $docId && $idSignatureRequest && $youSignDocId) {
				sleep(2);

				foreach ($paramModeleDoc['signataires'] as $indSigner => $paramSigner) {
					$signerEmail		= $loc[$paramSigner['email']];
					$signerFirstName	= $loc[$paramSigner['first_name']];
					$signerLastName		= $loc[$paramSigner['last_name']];
					$signerLocale		= $loc[$paramSigner['locale']] == 'EN' ? 'en' : 'fr';
					if ($signerEmail && $signerFirstName && $signerLastName) {
						try {
							$params	= [
								'idSignatureRequest'	=> $idSignatureRequest,
								'signerEmail'		=> $signerEmail,
								'signerFirstName'	=> $signerFirstName,
								'signerLastName'	=> $signerLastName,
								'signerLocale'		=> $signerLocale,
								];
							syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$indSigner params=".json_encode($params));
							$addSignerResult	= $signature->addSigner($params);
							if ($addSignerResult && $addSignerResult['idSigner']) {
								syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$indSigner OK: addSignerResult=".json_encode($addSignerResult));
								$youSignSignerId	= $addSignerResult['idSigner'];
							} else {
								syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa addSigner$indSigner ERR: addSignerResult=".json_encode($addSignerResult));
								$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner$indSigner ERR=".json_encode($addSignerResult);
								break;
							}

						} catch (\Exception $ex) {
							syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner$indSigner Exception=".$ex->getMessage());
							$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner$indSigner Exception=".$ex->getMessage();
							break;
						}
					} else {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner$indSigner : email=$signerEmail firstName=$signerFirstName lastName=$signerLastName : ignorer");

					}
				}
			}
		}

		if (!$erreurs) {
			if (1 && $docId && $idSignatureRequest && $youSignDocId) {
				sleep(2);

				## activation des signatures
				## ~~~~~~~~~~~~~~~~~~~~~~~~~
				try {
					$params	= [
						'idSignatureRequest'	=> $idSignatureRequest,
						];
					syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignature params=".json_encode($params));
					$activateResult	= $signature->activateSignatureRequest($params);
					if ($activateResult && $activateResult['idSignatureRequest']) {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignatureRequest OK: activateResult=".json_encode($activateResult));
					} else {
						syslog(LOG_DEBUG, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idResa=$idResa activateSignatureRequest ERR: activateResult=".json_encode($activateResult));
						$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId activateSignatureRequest ERR=".json_encode($activateResult);
					}

				} catch (\Exception $ex) {
					syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : idModele=$idModele idApiSignature=$idApiSignature addSigner Exception=".$ex->getMessage());
					$erreurs[]	= "idModele=$idModele idApiSignature=$idApiSignature idResa=$idResa docId=$docId addSigner Exception=".$ex->getMessage();
				}
			}
		}

		if (!$erreurs) {
			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : docId=$docId idSignatureRequest=$idSignatureRequest youSignDocId=$youSignDocId");
			if (1 && $docId && $idSignatureRequest && $youSignDocId) {
				## Mémorisation de l'identifiant de demande de signature
				## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				$data	= [ 'signState' => 102];
				$this->getDocumentTable()-> updateDocument($docId, $data);
			}

			syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] parAAK : nbContrats=$nbContrats");
		}

		return $erreurs;
	}

	##chargement de listes menage pour l'action dissociation famille
	public function loadMenagesAction()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = null;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$ids = $request->getPost('ids', array());
			$options = array();
			$success = false;
			$idReservation = '';
			$idLogement = '';
			$numeroChambre = '';
			$idCampagne = '';
			if(!empty($ids)) {
				foreach($ids as $idResa) {
					$resa = $this->getTableObjet('reservations')->select(array('id' => $idResa))->current();
					if($resa) {
						$options = $this->getResaTable()->getListeMenages($resa->idCampagne, $gestId, $adapter, $resa->idMenage);
						$success = true;
						$idReservation = $idResa;
						$idLogement = $resa->idLogement;
						$numeroChambre = $resa->numeroChambre;
						$idCampagne = $resa->idCampagne;
					} else {
						$msg = "Resa ID $idResa introuvable";
					}
				}
			} else {
				$msg = "IdResa vide";
			}

			## chargement changement logemet modal
			$conf = $this->getConfigurationTable()->getConfig(1);

			$htmlViewPart = new ViewModel();
			$htmlViewPart->setTerminal(true)
				->setTemplate('reservation/liste/changelogemodal')
				->setVariables(array(
									'conf' => $conf,
									'residences' => $this->getResidencesTable()->fetchByGest($gestId),
									'callFrom' => 'liste',
									'idResa' => $idReservation,
									'idLogement' => $idLogement,
									'numeroChambre' => $numeroChambre,
									'idCampagne' => $idCampagne,

				));

			$htmlOP = $this->getServiceLocator()
				->get('viewrenderer')
				->render($htmlViewPart);
			

			$view = new JsonModel(array(
				'success'	=> $success,
				'options' => $options,
				'msg'	=> $msg,
				'htmlOP' => $htmlOP,
				'idCampagne' => $idCampagne,
			));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function majLogementDissociationAction()
	{
		$msg = "";
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idReservation = $request->getPost('idReservation');
			$idOldLogement = $request->getPost('idOldLogement');
			$idNewLogement = (int)$request->getPost('idNewLogement');
			$dateDebut = $request->getPost('dateDebut');
			$dateFin = $request->getPost('dateFin');
			$idResa = $idReservation;

			$conf = $this->getConfigurationTable()->getConfig(1);
			$resa = $this->getResaTable()->getResaWithPms($idReservation);

			if (!$idNewLogement || $idNewLogement <= 0) {
				$calendar = $from == 'planning' ? $this->loadMyCalendar($filtres) : '';

				$view = new JsonModel(array(
					'success' => true,
					'msg' => "Erreur : Nouveau logement manquant, veuillez re essayer",
					'calendar' => $calendar,
					'isChanged' => false,
				));

				$view->setTerminal(true);
				return $view;
			}

			$logementNew = $this->getLogementTable()->getLogement($idNewLogement);
			$upDataResa = array();
			$upDataResa['idLogement'] = $idNewLogement;
			$upDataResa['numeroChambre'] = strtoupper($logementNew->numero);
			//if($dateDebut) $upDataResa['dateArrivee'] = date('Y-m-d',strtotime($dateDebut));
			//if($dateFin) $upDataResa['dateDepart'] = date('Y-m-d',strtotime($dateFin));
			if($dateDebut) $upDataResa['dateOption'] = date('Y-m-d',strtotime($dateDebut));//pour garder la date de l'affectation logement
			$upDataResa['idTypeLogementAttribue'] = $logementNew->idTypeLogement;


			$this->getResaTable()->updateResa($upDataResa, array('id' => $idResa));

			$operation = "Dissociation ménage sans logement";
			$log = new Logs();

			$log->dateOperation = date('Y-m-d H:i:s');
			$log->idGestionnaire = $gestId;
			$log->operation = $operation;
			$log->dataBefore = $resa;
			$log->dataAfter = $upDataResa;
			$log->tableName = "reservations";
			$log->idReservation = $resa->id;
			$log->idLocataire = $resa->idLocataire;
			$this->getLogsTable()->saveLogs($log);

			$view	= new JsonModel(array(
							'success' => true,
							'msg' => "Logement bien modifié, veuillez valider le changement de ménage",
							'isChanged' => true,
						));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	public function validerDissociationAction()
	{
		$msg = "";
		$request = $this->getRequest();
		if ($request->isXmlHttpRequest()) {
			$idReservation = $request->getPost('idReservation');
			$idLogement = $request->getPost('idLogement');
			$idMenage = $request->getPost('idMenage');

			$tableMenages = $this->getTableObjet('menages');
			$tableResa = $this->getTableObjet('reservations');
			$success = true;
			if($idReservation && $idMenage) {
				$resa = $tableResa->select(array('id' => $idReservation))->current();
				if(!$resa) {
					$view	= new JsonModel(array(
							'success' => false,
							'msg' => "Réservation ID=$idReservation introuvable",
						));

					$view->setTerminal(true);
					return $view;
				}

				$oldMenage = $tableMenages->select(array('id' => $resa->idMenage))->current();
				$oldMenageNom = $oldMenage ? $oldMenage->nom : '';

				$newMenage = $tableMenages->select(array('id' => $idMenage))->current();
				$newMenageNom = $newMenage ? $newMenage->nom : '';

				if($resa->idMenage == $idMenage) {
					$view	= new JsonModel(array(
							'success' => false,
							'msg' => "Veuillre choisir un ménage différent de $oldMenageNom pour dissocier",
						));

					$view->setTerminal(true);
					return $view;
				}
				//on vérifie si le ménage n'a pas déjà un chef de famille

				$row = $tableResa->select(array('idMenage' => $idMenage, 'idStatutFamilial' => 1))->current();
				if($row) {
					$view	= new JsonModel(array(
							'success' => false,
							'msg' => "Le ménage $newMenageNom a déjà un chef de famille",
						));

					$view->setTerminal(true);
					return $view;
				}

				$upDataResa = array();
				$upDataResa['idMenage'] = $idMenage;
				$upDataResa['idStatutFamilial'] = 1;//on le met par défaut comme chef de famille
				$this->getResaTable()->updateResa($upDataResa, array('id' => $idReservation));

				$this->saveMenageHistorique($resa->id, $resa->idMenage, $idMenage,'dissociation');

				$operation = "Dissociation ménage : changement ménage de $oldMenageNom en $newMenageNom";
				$log = new Logs();

				$log->dateOperation = date('Y-m-d H:i:s');
				$log->idGestionnaire = $gestId;
				$log->operation = $operation;
				$log->dataBefore = $resa;
				$log->dataAfter = $upDataResa;
				$log->tableName = "reservations";
				$log->idReservation = $resa->id;
				$log->idLocataire = $resa->idLocataire;
				$this->getLogsTable()->saveLogs($log);
				$msg = "Validation bien faite";


			} else {
				$success = true;
				if(!$idReservation) {
					$msg .= "ID réservation vide<br>";
				}
				if(!$idMenage) {
					$msg .= "ID ménage vide<br>";
				}
			}

			$view	= new JsonModel(array(
							'success' => $success,
							'msg' => $msg,
						));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## Onglet compte financier : envois des documents généré par mail
	public function envoyerMailCompteAction()
	{
		$request = $this->getRequest();

		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}

		$session = new Container('mailing');
		$session->mailOptions = null;

		if ($request->isXmlHttpRequest()) {
			$idLoc = $request->getPost('idLoc', null);
			$idResa = $request->getPost('idResa', null);
			$typeMail = $request->getPost('type', '');//facture/quittance/recu
			$noFacture = $request->getPost('noFacture', '');
			$success = false;
			$msg = '';
			$idModele = '';

			if ($typeMail && $noFacture && $idResa > 0) {
				//on vérifie si on a le modèle de type Documents en pièces jointes configuré
				$modeles = $this->getModelesMailTable()->getModelesByCode($typeMail);
				if($modeles->count() > 0) {
					$modele = $modeles->current();
					$idModele = $modele->id;

					try {
						## Les paramètres de envoyerMail sont envoyés au controlleur ReservationController.php
						## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						$options = array('typeMail' => $typeMail, 'idResa' => $idResa, 'idModele' => $idModele, 'noFacture' => $noFacture);
						$session->mailOptions = $options;


						$msg = "Chargement de modèle mailing";
						$success = true;

					} catch (\Exception $ex) {
						syslog(LOG_INFO, __FILE__.".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : Appel du controlleur de réservation : ERROR-exception=".$ex->getMessage());
						$msg = $ex->getMessage();
					}

				} else {
					$msg = "Aucun modèle mail de type Documents en pièces jointes configuré";
				}

			} else {
				if(!$idResa) {
					$msg = "idResa vide<br>";
				}
				if(!$typeMail) {
					$msg .= "typeMail vide<br>";
				}
				if(!$noFacture) {
					$msg .= "noFacture vide";
				}
			}

			$view = new JsonModel(array(
							'success'	=> $success,
							'msg'		=> $msg,
							'idModele'	=> $idModele,
				));

			$view->setTerminal(true);
			return $view;
		}
		exit();
	}

	## saveLogementPms forward vers LogementController.php saveLogementPmsForward
	private function saveLogementPms($idLogement){
		$return = $this->forward()->dispatch('Reservation\Controller\Logement', array(
				'action' => 'saveLogementPmsForward',
				'idLogement'	=> $idLogement,
			));
		return $return;
	}

	## récup de champs formulaires par campagne
	private function getChampsFormulaire($idCampagne){
		//recup de tout ls champs de la campagne
		$sql	= $this->getChampsFormulaireTable()->getSql();
		$select	= $sql->select();
		$select->join('formulaires', 'formulaires.id = champs_formulaires.idFormulaire', array('idForm' => 'id'));
		$select->join('champs_suivis', 'champs_suivis.id = champs_formulaires.idChampSuivis', array('idCS' => 'id', 'idTypeSuivis'), 'LEFT');
		$select->where(array('formulaires.idType' => '1', 'formulaires.idCampagne' => $idCampagne, 'champs_formulaires.active' => 1));
		$select->order(array('champs_formulaires.row', 'champs_formulaires.column'));
		## syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] idCampagne=$idCampagne sql=".$sql->getSqlstringForSqlObject($select));
		$champsResult = $this->getChampsFormulaireTable()->selectWith($select);
		$champsFormulaire = array();
		foreach ($champsResult as $cr) {
			$champsFormulaire['byId'][$cr->id]			= $cr;
			$champsFormulaire['byForm'][$cr->idFormulaire][]	= $cr->id;
			$champsFormulaire['byName'][$cr->name]			= $cr->id;
			//on save les champs dupliquer, celui de base avec ces copies
			if ($cr->idParent > 0) {
				$champsFormulaire['byParent'][$cr->idParent][]	= $cr->id;
			}
			//champs suivis par type suivis
			if ($cr->idChampSuivis > 0) {
				$champsFormulaire['byTypeSuivis'][$cr->idTypeSuivis][] = $cr;
			}
		}
		return $champsFormulaire;
	}

	private function getAllActions($resa){
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		$auth = $this->getServiceLocator()->get('zfcuser_auth_service');
		$gestId = 1;
		if ($auth->hasIdentity()) {
			$user = $auth->getIdentity();
			$gestId =  $user->getId();
		}
		$idProfile = $this->getUserTable()->getUserProfil($gestId)->role_id;

		$champsActionsParCondition = array('hide' => array(), 'show' => array());//on y stock les champs qui confirme des condition
		if(!$resa){
			return $champsActionsParCondition;
		}
		$idResa = $resa->id;

		$locAllInfosObj = $this->getLocatairesTable()->getAllInfosForPortail($resa->idLocataire, $adapter, $idResa, 0);
		$resaArr = get_object_vars($resa);
		unset($resaArr['id']);
		$locAllInfosObj = array_merge($locAllInfosObj, $resaArr);

		$idCampagne = $resa->idCampagne;
		$champsFormulaire = $this->getChampsFormulaire($idCampagne);
		$idsChampsActions = $this->getChampsLiesAuxActions($idCampagne);
		//on cherche tout les formulaire pour les actions
		$formsAll = $this->getFormulaireTableModel()->getAllBOForms($idCampagne, $idProfile, -1);

		foreach ($formsAll as $formRow) {
			if ($formRow->afficherEnBO == '-1') {
				continue;
			}
			$champsId = $champsFormulaire['byForm'][$formRow->id];
			if (empty($champsId)) {
				continue;
			}

			foreach ($champsId as $champId) {
				$champ	= $champsFormulaire['byId'][$champId];
				if (in_array($champ->id, $idsChampsActions)) {
					if(!array_key_exists($champ->equivalentSql, $locAllInfosObj) && $champ->valeurParDefaut) {
						$locAllInfosObj[$champ->equivalentSql] = $champ->valeurParDefaut;
					}
					if ($idResaADupliquer > 0) {
						if ($champ->dupliquerValeur != 1 && !empty($locAllInfosObj[$champ->equivalentSql])) {
							//on vide les champs a ne pas copier
							unset($locAllInfosObj[$champ->equivalentSql]);
						}
					}
					$dataActions = $locAllInfosObj;
					$currField = $champ->name;
					$dataActions['currentField'] = $currField;
					$dataActions['idCampagne'] = $idCamp;
					$dataActions['idTypeLocataire'] = $resa ? $resa->idTypeLocataire : null;
					$dataActions['idResa'] = $resa ? $resa->idResa : null;
					$returnActions = $this->loadActions($dataActions, $champsFormulaire);
					syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId currField=$currField nb_returnActions=".count($returnActions['actionResult']));

					// if ($champ->id == "3985") {
					// 	echo "<pre>";
					// 	var_dump($returnActions['actionResult']);
					// 	echo "</pre>";
					// 	die();
					// }

					if (!empty($returnActions['actionResult'])) {
						$acRows = $returnActions['actionResult'];
						foreach ($acRows as $acRow) {
							$ac = $acRow['action'];
							$chAc = $acRow['champ'];
							syslog(LOG_DEBUG, basename(__FILE__).".".__FUNCTION__.".".__LINE__."_$_SERVER[REMOTE_ADDR] : formId=".$formRow->id." champId=$champId currField=$currField : action=$ac champ=".$chAc->name." (".$chAc->id.")");
							if ($ac == "show") {
								if (!in_array($chAc->id, $champsActionsParCondition['show'])) {
									$champsActionsParCondition['show'][] = $chAc->id;
									//on applique le resultat sur les champs enfants
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];
										foreach ($champEnfants as $idCF) {
											$exitA = false;
											// on vérifie si le champ n'existe pas déjà dans hide
											foreach ($champsActionsParCondition['hide'] as $keyA => $valueH) {
												if ($valueH == $idCF) {
													$existA = true;
													break;
												}
											}

											if (!$existA) {
												$champsActionsParCondition['show'][] = $idCF;
											}
										}
									}

									// if ($chAc->id == "3191") {
									// 	echo "<pre>";
									// 	var_dump($champsFormulaire['byParent']);
									// 	echo "</pre>";
									// 	die();
									// }
								}
							} elseif ($ac == "hide") {
								if (!in_array($chAc->id, $champsActionsParCondition['hide'])) {
									$champsActionsParCondition['hide'][] = $chAc->id;

									//on applique le resultat sur les champs enfants
									if (!empty($champsFormulaire['byParent'][$chAc->id])) {
										$champEnfants = $champsFormulaire['byParent'][$chAc->id];
										foreach ($champEnfants as $idCF) {
											$exitA = false;
											// on vérifie si le champ n'existe pas déjà dans hide
											foreach ($champsActionsParCondition['show'] as $keyA => $valueH) {
												if ($valueH == $idCF) {
													$existA = true;
													break;
												}
											}

											if (!$existA) {
												$champsActionsParCondition['hide'][] = $idCF;
											}
										}
									}
								}
							} elseif($ac == "required") {
								$champsActionsParCondition['required'][] = $chAc->id;
							}
						}
					}
				}
			}
		}
		return $champsActionsParCondition;
	}

	public function getFormulairesLogeTable()
	{
		$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
		if(!$this->formulairesLogeTable) {
			$this->formulairesLogeTable = new formulairesLogeTable($adapter);
		}
		return $this->formulairesLogeTable;
	}


}
