<?php
/** derniere modification le 124/12/2023 à 09h40 par Pascal BLAIN (attention a la casse !)

 * Classe d'acces aux donnees. 
 * Utilise les services de la classe PDO pour l'application GSB
 * Les attributs sont tous statiques, les 4 premiers pour la connexion
 * $monPdo de type PDO 
 * $monPdoGsb qui contiendra l'unique instance de la classe
 
 * @link       http://www.php.net/manual/fr/book.pdo.php
 */

class PdoGsb
{
	private static $serveur = 'pgsql:host=localhost';
	private static $bdd = 'dbname=gsb2024';
	private static $user = 'postgres';
	private static $mdp = 'postgres';
	private static $monPdo;
	private static $monPdoGsb = null;
	/**
	 * Constructeur prive, cree l'instance de PDO qui sera sollicitee
	 * pour toutes les methodes de la classe
	 */
	private function __construct()
	{
		PdoGsb::$monPdo = new PDO(PdoGsb::$serveur . ';' . PdoGsb::$bdd, PdoGsb::$user, PdoGsb::$mdp);

		//PdoGsb::$monPdo->query("SET CHARACTER SET utf8");SET client_encoding = 'UTF8'; 
	}
	public function _destruct()
	{
		PdoGsb::$monPdo = null;
	}
	/**
	 * Fonction statique qui cree l'unique instance de la classe
	 * Appel : $instancePdoGsb = PdoGsb::getPdoGsb();
	 * @return l'unique objet de la classe PdoGsb
	 */
	public static function getPdoGsb()
	{
		if (PdoGsb::$monPdoGsb == null) {
			PdoGsb::$monPdoGsb = new PdoGsb();
		}
		return PdoGsb::$monPdoGsb;
	}

	/**
	 * Retourne les informations d'un utilisateur
	 * @param $login 
	 * @param $mdp
	 * @return l'id, le nom et le prenom sous la forme d'un tableau associatif 
	 */
	public function getInfosUtilisateur($login, $mdp)
	{
		$req = "select \"uId\" as id, \"uNom\" as nom, \"uPrenom\" as prenom, \"uStatut\" as statut
				from utilisateur
				where \"uLogin\"='$login' 
				and \"uMdp\"='$mdp'";
		$req = $this->entourerNoms($req);
		//echo $req;
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$ligne = $rs->fetch();
		return $ligne;
	}

	/**
	 * Retourne les informations de la table Visiteur
	 * @return un tableau associatif 
	 */
	public function getLesVisiteurs()
	{







	}
	/**
	 * Retourne deux valeurs indiquant si un ajout de frais est possible
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @paral etatRemboursement
	 */
	public function getAjoutFraisPossible($idVisiteur, $leMois, $etatRemboursement)
	{
		$possible = array('forfait' => "non", 'horsForfait' => "non", 'modifComptable' => 'non');
		if ($_SESSION['statut'] == '1' && $etatRemboursement == 'CR') {
			$req = "select	count(*) as nbForfaits
				from	forfait 
				where	fId not in (select lfForfait
									from ligneForfait
									where lfVisiteur='$idVisiteur' 
									and lfMois = '$leMois')";
			//$req = $this->entourerNoms($req);									
			$rs = PdoGsb::$monPdo->query($req);
			if ($rs === false) {
				afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
			}
			$laLigne = $rs->fetch();
			if ($laLigne['nbForfaits'] == 0 ? $possible = array('forfait' => "non", 'horsForfait' => "oui", 'modifComptable' => 'non') : $possible = array('forfait' => "oui", 'horsForfait' => "oui", 'modifComptable' => 'non'))
				;
		} else {
			if ($_SESSION['statut'] != '1' && $etatRemboursement == 'CL') {
				$possible = array('forfait' => "non", 'horsForfait' => "non", 'modifComptable' => "oui");
			}
		}
		return $possible;
	}

	/**
	 * Retourne les informations pour ajout d'un nouveau frais forfaitaire
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return l'id, le libell, le montant sous la forme d'un tableau associatif 
	 */
	public function getLesForfaitsPossibles()
	{
		$req = "select	\"fId\", \"fLibelle\", \"fMontant\"
				from	forfait";
		//$req = $this->entourerNoms($req); 
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}

	/**
	 * Retourne le tarif KM pour un motorisation et une puissance donnee a une date 
	 */
	public function getPrixKm($idVisiteur, $leMois)
	{
		$laDate = substr($leMois, 0, 4) . '-' . substr($leMois, 4, 2) . '-01';

		$req = "SELECT 1;";

		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		return $laLigne;
	}

	/** 
	 * Retourne sous forme d'un tableau associatif toutes les lignes de frais hors forfait concernees par les deux arguments
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return tous les champs des lignes de frais hors forfait sous la forme d'un tableau associatif 
	 */
	public function getLesFraisHorsForfait($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}

	/**
	 */
	public function getLesFraisReportes($idVisiteur, $mois, $justifies)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}

	/**
	 * Retourne le nombre de justificatif d'un Visiteurpour un mois donnee
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return le nombre entier de justificatifs 
	 */
	public function getNbjustificatifs($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		return $laLigne['nb'];
	}

	/**
	 * Retourne le montant valide pour un remboursement (cumul des frais forfaitaires et des autres depenses (hors forfaits)
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return le montant 
	 */
	public function getMontantValide($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		$montantValide = $laLigne['montant'];
		return $montantValide;
	}

	/**
	 * Retourne sous forme d'un tableau associatif toutes les lignes de frais au forfait concernees par les deux arguments
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return l'id, le libelle et la quantite sous la forme d'un tableau associatif 
	 */
	public function getLesFraisForfait($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}

	/**
	 * Met a jour la table ligneForfait pour un Visiteur et un mois donne en enregistrant le nouveau montant
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $qte
	 */
	public function getUnFraisForfait($idVisiteur, $mois, $forfait)
	{
		$req = "select lfVisiteur, lfMois, lfForfait, lfQuantite, lfMontant, fLibelle
				from ligneForfait inner join forfait on ligneForfait.lfForfait=forfait.fId
				where lfVisiteur= '$idVisiteur' 
				and lfMois = '$mois'
				and lfForfait = '$forfait'";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		return $laLigne;
	}

	/**
	 * Met a jour la table ligneForfait pour un Visiteur et un mois donne en enregistrant le nouveau montant
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $qte
	 */
	public function majFraisForfait($idVisiteur, $mois, $forfait, $qte)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * supprime une ligneForfait pour un Visiteur et un mois donne 
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $forfait
	 */
	public function supprimerFraisForfait($idVisiteur, $mois, $forfait)
	{
		$req = $req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * ajoute une ligne dans la table ligneForfait pour un Visiteur et un mois donne
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $forfait
	 * @param $qte
	 * @param $montant
	 */
	public function ajoutFraisForfait($idVisiteur, $mois, $forfait, $qte, $montant)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Met a jour la table ligneForfait pour un Visiteur et un mois donne en enregistrant le nouveau montant
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $qte
	 */
	public function getUnFraisHorsForfait($idFrais)
	{
		$req = $req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		return $laLigne;
	}

	/**
	 * Met ajour la table ligneHorsForfait (nouvelles valeurs)
	 */
	public function majFraisHorsForfait($idFrais, $date, $libelle, $montant)
	{
		$dateFr = dateFrancaisVersAnglais($date);
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Met a jour la table ligneHorsForfait pour report au mois suivant
	 */
	public function transfertFraisHorsForfait($idFrais, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Cree un nouveau frais hors forfait pour un Visiteurun mois donne a partir des parametres
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @param $libelle : le libelle du frais
	 * @param $date : la date du frais au format franÃ§ais jj//mm/aaaa
	 * @param $montant : le montant
	 */
	public function ajoutFraisHorsForfait($idVisiteur, $mois, $date, $libelle, $montant)
	{
		$dateFr = dateFrancaisVersAnglais($date);
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Supprime le frais hors forfait dont l'id est passe en argument 
	 * @param $idFrais 
	 */
	public function supprimerFraisHorsForfait($idFrais, $libelle)
	{









	}

	/**
	 * Retourne les mois pour lesquel un Visiteura une fiche de frais 
	 * @param $idVisiteur 
	 * @return un tableau associatif de clefs un mois -aaaamm- et de valeurs l'anne et le mois correspondant 
	 */
	public function getLesMoisDisponibles($idVisiteur)
	{
		$tabMois = array('01' => "Janvier",
			'02' => "F&eacute;vrier",
			'03' => "Mars",
			'04' => "Avril",
			'05' => "Mai",
			'06' => "Juin",
			'07' => "Juillet",
			'08' => "Ao&ucirc;t",
			'09' => "Septembre",
			'10' => "Octobre",
			'11' => "Novembre",
			'12' => "D&eacute;cembre");
		$req = "select	\"rMois\" as mois 
				from 	remboursement 
				where	\"rVisiteur\"='$idVisiteur' ";
		if ($_SESSION['statut'] <> '1') {
			$req = $req . "and	\"rEtat\"<>'CR'";
		}
		$req = $req . " order by \"rMois\" desc limit 12";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		$lesMois = array();
		$laLigne = $rs->fetch();
		while ($laLigne != null) {
			$mois = $laLigne['mois'];
			$numAnnee = substr($mois, 0, 4);
			$numMois = $tabMois[substr($mois, 4, 2)];
			$lesMois["$mois"] = array("mois" => "$mois", "numAnnee" => "$numAnnee", "numMois" => "$numMois");
			$laLigne = $rs->fetch();
		}
		return $lesMois;
	}

	/**
	 */
	public function existeRemboursement($idVisiteur, $mois)
	{
		$req = "select	count(*) as nb
				from	remboursement
				where	\"rVisiteur\"='$idVisiteur'
				and		\"rMois\"='$mois'";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		$laLigne = $rs->fetch();
		return $laLigne['nb'];
	}

	/**
	 */
	public function getNbRemboursementsAValider()
	{
		$req = "SELECT 1 as nb;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		$laLigne = $rs->fetch();
		return $laLigne['nb'];
	}

	/**
	 */
	public function creeNouveauRemboursement($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Retourne les informations d'une fiche de frais d'un Visiteur pour un mois donne
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 * @return un tableau avec des champs de jointure entre une fiche de frais et la ligne d'etat 
	 */
	public function getInfosRemboursement($idVisiteur, $mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la lecture ..", $req, PdoGsb::$monPdo->errorInfo());
		}
		$laLigne = $rs->fetch();
		return $laLigne;
	}

	/**
	 * Actualise le montant valide et le nb de justificatifs recus 
	 */
	public function valideRemboursement($idVisiteur, $mois)
	{
		$NbJustificatifs = $this->getNbjustificatifs($idVisiteur, $mois);
		$montantValide = $this->getMontantValide($idVisiteur, $mois);
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Modifie l'etat et la date de modification d'une fiche de frais
	 * Modifie le champ idEtat et met la date de modif a aujourd'hui
	 * @param $idVisiteur 
	 * @param $mois sous la forme aaaamm
	 */
	public function majRemboursement($idVisiteur, $mois, $etat)
	{
		$req = "update	remboursement set \"rEtat\" = '$etat', \"rDateModif\" = now() 
				where	\"rVisiteur\"='$idVisiteur' 
				and 	\"rMois\"='$mois'";
		PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Clos les fiches de frais
	 * Modifie le champ idEtat et met la date de modif a aujourd'hui
	 */
	public function clotureMois($mois)
	{
		$req = "SELECT 1;";
		//$req = $this->entourerNoms($req);
		//PdoGsb::$monPdo->exec($req);
	}

	/**
	 * Retourne les informations de la table TYPEPARAMETRE
	 */
	public function getLesParametres()
	{
		$req = "SELECT \"tlId\", \"tlLibelle\", \"tlBooleen\", \"tlChoixMultiple\", \"tlCumul\"
					FROM \"typeParametre\"
					ORDER BY \"tlLibelle\";";
		$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la recherche dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}

	/**
	 * Retourne dans un tableau associatif les informations de la table PARAMETRE (pour un type particulier)
	 */
	public function getParametre($type)
	{
		$req = "SELECT \"pIndice\", \"pLibelle\"
				FROM parametre
				WHERE \"pType\"='$type'
				ORDER by \"pIndice\";";
		//echo $req;
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la recherche des parametres dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
		$lesLignes = $rs->fetchAll();
		return $lesLignes;
	}
	/**
	 * Retourne dans un tableau associatifles informations de la table PARAMETRE (pour un type particulier)
	 */
	public function getInfosParam($type, $valeur)
	{
		if ($valeur == "NULL") {
			$req = "SELECT \"pType\", max(\"pIndice\")+1 AS pIndice, ' ' AS pLibelle, \"tlLibelle\", \"pPlancher\", \"pPlafond\"
						 FROM parametre INNER JOIN \"typeParametre\" ON \"typeParametre\".\"tlId\"=parametre.\"pType\"
						 WHERE pType='$type';";
		} else {
			$req = "SELECT \"pType\", \"pIndice\", \"pLibelle\", \"tlLibelle\", \"pPlancher\", \"pPlafond\"
						 FROM parametre INNER JOIN \"typeParametre\" ON \"typeParametre\".\"tlId\"=parametre.\"pType\"
						 WHERE \"pType\"='$type'
						 AND \"pIndice\" like '$valeur';";
		}
		$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->query($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la recherche dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
		$ligne = $rs->fetch();
		return $ligne;
	}


	/**
	 * Met a jour une ligne de la table PARAMETRE
	 */
	public function majParametre($type, $valeur, $libelle, $territoire, $dep, $plancher, $plafond)
	{
		$req = "UPDATE parametre SET \"pLibelle\"='$libelle', \"pPlancher\"=$plancher, \"pPlafond\"=$plafond
					WHERE \"pType\"='$type'
					AND \"pIndice\"=$valeur;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->exec($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la mise a jour des parametres dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
	}

	/**
	 * supprime une ligne de la table PARAMETRE 
	 */
	public function supprimeParametre($type, $valeur)
	{
		$req = "DELETE 
				FROM parametre
				WHERE \"pType\"='$type'
				AND \"pIndice\"=$valeur;";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->exec($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de la suppression d'un parametre dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
	}

	/**
	 * ajoute une ligne dans la table PARAMETRE
	 */
	public function ajoutParametre($type, $valeur, $libelle, $territoire, $dep, $plancher, $plafond)
	{
		$req = "INSERT INTO parametre 
					(\"pType\", \"pIndice\", \"pLibelle\", \"pPlancher\", \"pPlafond\") 
					VALUES ('$type', $valeur, '$libelle', $plancher, $plafond);";
		//$req = $this->entourerNoms($req);
		$rs = PdoGsb::$monPdo->exec($req);
		if ($rs === false) {
			afficherErreurSQL("Probleme lors de l'insertion d'un parametre dans la base de donn&eacute;es.", $req, PdoGsb::$monPdo->errorInfo());
		}
	}
	/**
	 * Fonction pour entourer les noms de tables et de champs par des guillemets doubles
	 */
	private function entourerNoms($requete)
	{
		$pattern = '/SELECT(.*?)[\n\r\s]FROM/i';
		echo 'le patron : ' . $pattern . ' la requete : ' . $requete;
		preg_match_all($pattern, $requete, $matches);

		if (isset($matches[1])) {
			var_dump($matches);
			foreach ($matches[1] as $match) {
				// Ajouter des guillemets doubles autour des noms de tables et de champs
				$noms_entoures = preg_replace_callback('/\b([A-Za-z_][A-Za-z0-9_]*)\b/', function ($match) {
					return '\"' . $match[0] . '\"';
				}, $match);

				$requete = str_replace($match, $noms_entoures, $requete);
			}
		}
		//echo $requete;
		return $requete;
	}
}
?>