<?php
define("WEB_EOL","<br/>");
// ==========================================================
// --- Fonction d'affichage de l'état de tous les comptes ---
// ==========================================================
function Affiche_Etat_Comptes($texte)
{
 global $ERR_TRAIT,$TYPE_DBB,$SERVEUR,$BASEDD,$LOGIN_ADM,$MDP_ADM,$TABLECOMPTES,$TABLECLIENTS;
 try
 {
  // -- contexte pour le message d'erreur ---
  $contexte="Connexion base de donn&eacute;es";
  // --- connexion de la base de donn&eacute;es ---
  $bdd = new PDO($TYPE_DBB.":host=".$SERVEUR.";dbname=".$BASEDD,$LOGIN_ADM,$MDP_ADM,
         array(PDO::ATTR_PERSISTENT => true));
  // --- définition du codage en UTF8 ---
  $bdd->exec("SET CHARACTER SET utf8");     
  // --- initialisation des Exceptions PDO pour prepare ---
  $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  // --- limitation aux comptes de dépôt ---
  $type_compte="Compte_Dépôts";
  // --- on affiche tous les comptes courant Avant le virement ---
  // -- contexte pour le message d'erreur ---
  $contexte="Probl&egrave;me de requ&ecirc;te";  
  // --- préparation de la requête ---
  $requete_sql='SELECT cb.ID_Cpt,cb.Agence,cb.Numero,cb.Type,cl.Nom,cl.Prenom,ROUND(cb.Solde,2) Solde_Compte FROM '.$TABLECOMPTES.' cb INNER JOIN '.$TABLECLIENTS.' cl ON cb.ID_Clt=cl.ID_Clt WHERE Type=:type_compte';
  $RequetePreparee = $bdd->prepare($requete_sql);
  // --- liaison avec les paramètres ---
  $RequetePreparee->bindParam(':type_compte', $type_compte);
  // --- exécution de la requête ---
  $RequetePreparee->execute();
  // ---retourne un tableau associatif ---
  $RequetePreparee->setFetchMode(PDO::FETCH_ASSOC); 
  // --- boucle de traitement de chaque client --- 
  $Tab_Comptes=$RequetePreparee->fetchAll();
  // --- Conversion de la colonne solde au format français ---
  foreach ($Tab_Comptes as $Num => $un_cpt)
  {
   $un_cpt['Solde_Compte']=number_format($un_cpt['Solde_Compte'],2,","," ")." €";
   $Tab_Comptes[$Num]=$un_cpt;
  }
  // --- affichage des données retournées ---
  Affichage_Liste_Comptes($texte,$Tab_Comptes);
  // --- fermeture de la requête ---
  $RequetePreparee->closeCursor();
  return $Tab_Comptes;
 }
 catch(Exception $e)
 {
  $TitreMessage = $contexte       ;
  $TexteMessage = $e->getMessage();
  Affiche_Message_Erreur($TitreMessage,$TexteMessage);
  $ERR_TRAIT=true;
 }
}
// =======================================================
// --- fonction outil d'affichage du message d'erreur  ---
// =======================================================
function Affiche_Message_Erreur($titre,$message)
{
 ?>
 <fieldset>
 <legend><?php echo $titre ?></legend><br/>
 <b><?php echo $message ?></b><br />
 </fieldset>
 <?php
}
// ============================================================
// --- fonction outil d'affichage d'un tableau de comptes  ---
// ============================================================
function Affichage_Liste_Comptes($titre,$tcomptes)
{
 // --- affichage entête du tableau ---
 reset($tcomptes);
 $un_compte=current($tcomptes);
 $liste_champs=array_keys($un_compte);
 ?>
 <table summary="Tableau de r&eacute;sultat">
  <caption><?php echo $titre;?></caption>
  <thead>
  <tr>
  <!-- entête du tableau -->
  <?php
  echo "<tr>";
  $nbchamps=0;
  foreach($liste_champs as $nom_champ)
  {
   echo "<th>$nom_champ</th>";
   $nbchamps++;
  }
  echo "</tr>";
  // --- affichage des lignes du tableau ---
  if (count($tcomptes) ==0)
  {
   echo "<td colspan=\"$nbchamps\"><b>Aucun compte &agrave; afficher</b></td>";
  }
  else
  {
   foreach ($tcomptes as $indice => $un_compte)
   {
    echo "<tr>";
    // importation des variables à partir de l'étiquette des champs
    extract($un_compte,EXTR_OVERWRITE);
    echo "<tr>";
    foreach($liste_champs as $nom_champ)
    {
     $val=$$nom_champ;
     echo "<td>$val</td>";
    }
    echo "</tr>";
   }
  }
  ?>
 </table>
 <?php
}
// ==========================================================
// --- Fonction d'information sur l'état d'un seul compte ---
// ==========================================================
function Info_Compte($compte)
{
 global $ERR_TRAIT,$TYPE_DBB,$SERVEUR,$BASEDD,$LOGIN_ADM,$MDP_ADM,$TABLECOMPTES,$TABLECLIENTS;
 try
 {
  // -- contexte pour le message d'erreur ---
  $contexte="Connexion base de donn&eacute;es";
  // --- connexion de la base de donn&eacute;es ---
  $bdd = new PDO($TYPE_DBB.":host=".$SERVEUR.";dbname=".$BASEDD,$LOGIN_ADM,$MDP_ADM,
         array(PDO::ATTR_PERSISTENT => true));
  // --- définition du codage en UTF8 ---
  $bdd->exec("SET CHARACTER SET utf8");     
  // --- initialisation des Exceptions PDO pour prepare ---
  $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $contexte="Probl&egrave;me de requ&ecirc;te sur la table";
  // --- préparation de la requête ---
  $requete_sql='SELECT cb.ID_Cpt,cb.Agence,cb.Numero,cb.Type,cl.Nom,cl.Prenom,ROUND(cb.Solde,2) Solde_Compte FROM '.$TABLECOMPTES.' cb INNER JOIN '.$TABLECLIENTS.' cl ON cb.ID_Clt=cl.ID_Clt WHERE ID_Cpt=:compte';
  $RequetePreparee = $bdd->prepare($requete_sql);
  // --- liaison avec les paramètres ---
  $RequetePreparee->bindParam(':compte', $compte, PDO::PARAM_INT);
  // --- exécution de la requête ---
  $RequetePreparee->execute();
  // ---retourne un tableau associatif ---
  $RequetePreparee->setFetchMode(PDO::FETCH_ASSOC); 
  // --- boucle de traitement de chaque client --- 
  $Tab_Infos_Cpt=$RequetePreparee->fetchAll();
  // --- Conversion de la colonne solde au format français ---
  foreach ($Tab_Infos_Cpt as $Num => $un_cpt)
  {
   $un_cpt['Solde_Compte']=number_format($un_cpt['Solde_Compte'],2,","," ")." €";
   $Tab_Infos_Cpt[$Num]=$un_cpt;
  }
  $Tab_Infos_Un_Cpt=$Tab_Infos_Cpt[0];
  return $Tab_Infos_Un_Cpt;
 }
 catch(Exception $e)
 {
  $TitreMessage = $contexte       ;
  $TexteMessage = $e->getMessage();
  Affiche_Message_Erreur($TitreMessage,$TexteMessage);
  $ERR_TRAIT=true;
 }   
}
// ============================
// --- Fonction de virement ---
// ============================
function Virement($NumCptDebit,$NumCptCredit,$MtVirt)
{
 global $ERR_TRAIT,$TYPE_DBB,$SERVEUR,$BASEDD,$LOGIN_ADM,$MDP_ADM,$TABLECOMPTES,$TABLECLIENTS;
 $virement_effectue   = true ;
 $ConnexionBDD        = false;
 $TransactionDemarree = false;
 try
 {
  // -- contexte pour le message d'erreur ---
  $contexte="Connexion base de donn&eacute;es";
  // --- connexion de la base de donn&eacute;es ---
  $bdd = new PDO($TYPE_DBB.":host=".$SERVEUR.";dbname=".$BASEDD,$LOGIN_ADM,$MDP_ADM,
         array(PDO::ATTR_PERSISTENT => true));
  $ConnexionBDD=true;
  // --- initialisation des Exceptions PDO pour prepare ---
  $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  // --- définition du codage en UTF8 ---
  $bdd->exec("SET CHARACTER SET utf8");     
  // --- on gère le virement  dans une transaction SQL ---
  // ================================
  // === on débute la transaction ===
  // ================================
  // -- contexte pour le message d'erreur ---
  $contexte="Initialisation virement";  
  $bdd->beginTransaction() ;
  $TransactionDemarree=true;
  // ===========================
  // === on débite le compte ===
  // ===========================
  // -- contexte pour le message d'erreur ---
  $contexte="D&eacute;bit du compte" ;
  // --- préparation de la requête ---
  $requete_sql='UPDATE '.$TABLECOMPTES.' SET Solde=Solde+:MontantVir WHERE Id_Cpt=:NumCptOperation';
  $reponse = $bdd->prepare($requete_sql);
  // --- liaison avec les paramètres ---
  $reponse->bindParam(':MontantVir', $MontantVir);
  $reponse->bindParam(':NumCptOperation', $NumCptOperation, PDO::PARAM_INT);
  // --- affectation des valeurs pour les paramètres ---
  $MontantVir      = -$MtVirt     ;
  $NumCptOperation = $NumCptDebit ;
  // --- exécution de la requête ---
  $reponse->execute()    ;
  // --- fermeture de la requête --- 
  $reponse->closeCursor();
  // ============================
  // === on crédite le compte ===
  // ============================
  // -- contexte pour le message d'erreur ---
  $contexte="Cr&eacute;dit du compte";  
  // --- La requête est déjà préparée, elle ne change pas ---
  // --- les paramètres sont déjà liés (bind) ils ne changent pas ---
  // --- affectation des valeurs pour les paramètres ---
  $MontantVir      = +$MtVirt      ;
  $NumCptOperation = $NumCptCredit ;
  // --- exécution de la requête ---
  $reponse->execute()    ;
  // --- fermeture de la requête --- 
  $reponse->closeCursor();
  // ================================
  // === on valide la transaction ===
  // ================================
  // --- si aucune erreur, on valide la transaction ---
  $contexte = "Validation virement";
  $reponse  = $bdd->commit();
 }
 catch(Exception $e)
 {
  // ================================
  // === on annule la transaction ===
  // ================================
  if ($ConnexionBDD && $TransactionDemarree)
  {
   try
   {
    $bdd->rollback();
   }
   catch(Exception $er)
   {
    $TitreMessage = 'Probl&egrave;me sur le virement - Transaction annul&eacute;e';
    $TexteMessage = 'Annulation : '.$er->getMessage();
    Affiche_Message_Erreur($TitreMessage,$TexteMessage);
    $virement_effectue=false;
   }
  }
  $TitreMessage = 'Probl&egrave;me sur le virement - Transaction annul&eacute;e';
  $TexteMessage = $contexte.' : '.$e->getMessage();
  Affiche_Message_Erreur($TitreMessage,$TexteMessage);
  $virement_effectue=false;
 }
 return $virement_effectue;
}
?>