diff --git a/htdocs/facture.class.php b/htdocs/facture.class.php
index 3613a281472b17adceda8cabc26ab974c26d28b3..38c26380a013f8d7f10e1a2a04d97e85bd4f5003 100644
--- a/htdocs/facture.class.php
+++ b/htdocs/facture.class.php
@@ -55,6 +55,8 @@ class Facture
     var $propalid;
     var $projetid;
     var $prefixe_facture;
+    var $cond_reglement;
+    var $mode_reglement;
 
     /**
     *    \brief  Constructeur de la classe
@@ -330,10 +332,11 @@ class Facture
         $sql = "SELECT f.fk_soc,f.facnumber,f.amount,f.tva,f.total,f.total_ttc,f.remise,f.remise_percent";
         $sql .= ",".$this->db->pdate("f.datef")." as df,f.fk_projet";
         $sql .= ",".$this->db->pdate("f.date_lim_reglement")." as dlr";
-        $sql .= ", c.rowid as cond_regl_id, c.libelle, c.libelle_facture";
         $sql .= ", f.note, f.paye, f.fk_statut, f.fk_user_author";
-        $sql .= ", f.fk_mode_reglement";
+        $sql .= ", f.fk_mode_reglement, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle";
+        $sql .= ", f.fk_cond_reglement, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_facture";
         $sql .= " FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."cond_reglement as c";
+        $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON f.fk_mode_reglement = p.id";
         $sql .= " WHERE f.rowid=$rowid AND c.rowid = f.fk_cond_reglement";
         if ($societe_id > 0)
         {
@@ -347,28 +350,30 @@ class Facture
             {
                 $obj = $this->db->fetch_object($result);
 
-                $this->id                 = $rowid;
-                $this->datep              = $obj->dp;
-                $this->date               = $obj->df;
-                $this->ref                = $obj->facnumber;
-                $this->amount             = $obj->amount;
-                $this->remise             = $obj->remise;
-                $this->total_ht           = $obj->total;
-                $this->total_tva          = $obj->tva;
-                $this->total_ttc          = $obj->total_ttc;
-                $this->paye               = $obj->paye;
-                $this->remise_percent     = $obj->remise_percent;
-                $this->socidp             = $obj->fk_soc;
-                $this->statut             = $obj->fk_statut;
-                $this->date_lim_reglement = $obj->dlr;
-                $this->cond_reglement_id  = $obj->cond_regl_id;
-                $this->cond_reglement     = $obj->libelle;
-                $this->cond_reglement_facture = $obj->libelle_facture;
-                $this->projetid           = $obj->fk_projet;
-                $this->note               = stripslashes($obj->note);
-                $this->user_author        = $obj->fk_user_author;
-                $this->lignes             = array();
-                $this->mode_reglement     = $obj->fk_mode_reglement;
+                $this->id                     = $rowid;
+                $this->datep                  = $obj->dp;
+                $this->date                   = $obj->df;
+                $this->ref                    = $obj->facnumber;
+                $this->amount                 = $obj->amount;
+                $this->remise                 = $obj->remise;
+                $this->total_ht               = $obj->total;
+                $this->total_tva              = $obj->tva;
+                $this->total_ttc              = $obj->total_ttc;
+                $this->paye                   = $obj->paye;
+                $this->remise_percent         = $obj->remise_percent;
+                $this->socidp                 = $obj->fk_soc;
+                $this->statut                 = $obj->fk_statut;
+                $this->date_lim_reglement     = $obj->dlr;
+                $this->mode_reglement_id      = $obj->fk_mode_reglement;
+                $this->mode_reglement_code    = $obj->mode_reglement_code;
+                $this->mode_reglement         = $obj->mode_reglement_libelle;
+                $this->cond_reglement_id      = $obj->fk_cond_reglement;
+                $this->cond_reglement         = $obj->cond_reglement_libelle;
+                $this->cond_reglement_facture = $obj->cond_reglement_libelle_facture;
+                $this->projetid               = $obj->fk_projet;
+                $this->note                   = stripslashes($obj->note);
+                $this->user_author            = $obj->fk_user_author;
+                $this->lignes                 = array();
 
                 if ($this->statut == 0)
                 {
@@ -437,6 +442,7 @@ class Facture
         else
         {
             dolibarr_syslog("Erreur Facture::Fetch rowid=$rowid Erreur dans fetch de la facture");
+            $this->error=$this->db->error();
             return -1;
         }
     }
diff --git a/htdocs/html.form.class.php b/htdocs/html.form.class.php
index d7bd02fa6c2b5266095d2d99b331260536664971..cf52709a43299fda4b16f57885a7e666ec776120 100644
--- a/htdocs/html.form.class.php
+++ b/htdocs/html.form.class.php
@@ -37,33 +37,38 @@
 
 class Form
 {
-  var $db;
-  var $errorstr;
-  
-  /**
+    var $db;
+    var $errorstr;
+    
+    var $cache_types_paiements_code=array();
+    var $cache_types_paiements_libelle=array();
+    var $cache_conditions_paiements_code=array();
+    var $cache_conditions_paiements_libelle=array();
+
+
+    /**
     	\brief     Constructeur
         \param     DB      handler d'acc�s base de donn�e
-  */
-	
-  function Form($DB)
-  {
-    $this->db = $DB;
+    */
     
-    return 1;
-  }
+    function Form($DB)
+    {
+        $this->db = $DB;
+        
+        return 1;
+    }
   
-  /**
-   *    \brief      Retourne la liste d�roulante des d�partements/province/cantons tout pays confondu ou pour un pays donn�.
-   *    \remarks    Dans le cas d'une liste tout pays confondus, l'affichage fait une rupture sur le pays.
-   *    \remarks    La cle de la liste est le code (il peut y avoir plusieurs entr�e pour
-   *                un code donn�e mais dans ce cas, le champ pays diff�re).
-   *                Ainsi les liens avec les d�partements se font sur un d�partement ind�pendemment de nom som.
-   *    \param      selected        code forme juridique a pr�s�lectionn�
-   *    \param      pays_code       0=liste tous pays confondus, sinon code du pays � afficher
-   */
-
-  function select_departement($selected='',$pays_code=0)
-  {
+    /**
+     *    \brief      Retourne la liste d�roulante des d�partements/province/cantons tout pays confondu ou pour un pays donn�.
+     *    \remarks    Dans le cas d'une liste tout pays confondus, l'affichage fait une rupture sur le pays.
+     *    \remarks    La cle de la liste est le code (il peut y avoir plusieurs entr�e pour
+     *                un code donn�e mais dans ce cas, le champ pays diff�re).
+     *                Ainsi les liens avec les d�partements se font sur un d�partement ind�pendemment de nom som.
+     *    \param      selected        code forme juridique a pr�s�lectionn�
+     *    \param      pays_code       0=liste tous pays confondus, sinon code du pays � afficher
+     */
+    function select_departement($selected='',$pays_code=0)
+    {
     global $conf,$langs;
     $langs->load("dict");
     
@@ -445,87 +450,199 @@ class Form
    *    \param      filtretype      Pour filtre sur type de produit
    *    \param      limit           Limite sur le nombre de lignes retourn�
    */
-  function select_produits($selected='',$htmlname='productid',$filtretype='',$limit=20)
-  {
-    global $langs,$conf;
+    function select_produits($selected='',$htmlname='productid',$filtretype='',$limit=20)
+    {
+        global $langs,$conf;
     
-    $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration";
-    $sql.= " FROM ".MAIN_DB_PREFIX."product as p ";
-    $sql.= " WHERE p.envente = 1";
-    if ($filtretype && $filtretype != '') $sql.=" AND p.fk_product_type=".$filtretype;
-    $sql.= " ORDER BY p.nbvente DESC";
-    if ($limit) $sql.= " LIMIT $limit";
+        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration";
+        $sql.= " FROM ".MAIN_DB_PREFIX."product as p ";
+        $sql.= " WHERE p.envente = 1";
+        if ($filtretype && $filtretype != '') $sql.=" AND p.fk_product_type=".$filtretype;
+        $sql.= " ORDER BY p.nbvente DESC";
+        if ($limit) $sql.= " LIMIT $limit";
     
-    $result=$this->db->query($sql);
-    if ($result)
-    {
-    	print '<select class="flat" name="'.$htmlname.'">';
-        print "<option value=\"0\" selected=\"true\">&nbsp;</option>";
-
-        $num = $this->db->num_rows($result);
-        $i = 0;
-        while ($i < $num)
+        $result=$this->db->query($sql);
+        if ($result)
+        {
+            print '<select class="flat" name="'.$htmlname.'">';
+            print "<option value=\"0\" selected=\"true\">&nbsp;</option>";
+    
+            $num = $this->db->num_rows($result);
+            $i = 0;
+            while ($i < $num)
+            {
+                $objp = $this->db->fetch_object($result);
+                $opt = "<option value=\"$objp->rowid\">[$objp->ref] $objp->label - $objp->price ".$langs->trans("Currency".$conf->monnaie);
+                if ($objp->duration) $opt .= " - ".$objp->duration;
+                $opt .= "</option>\n";
+                print $opt;
+                $i++;
+            }
+            print '</select>';
+    
+            $this->db->free($result);
+        }
+        else
         {
-            $objp = $this->db->fetch_object($result);
-            $opt = "<option value=\"$objp->rowid\">[$objp->ref] $objp->label - $objp->price ".$langs->trans("Currency".$conf->monnaie);
-            if ($objp->duration) $opt .= " - ".$objp->duration;
-            $opt .= "</option>\n";
-            print $opt;
-            $i++;
+            dolibarr_print_error($db);
         }
-        print '</select>';
-        
-        $this->db->free($result);
     }
-    else
+  
+
+    /**
+     *    \brief      Charge dans cache la liste des conditions de paiements possibles
+     *    \param      selected        Condition de paiement pr�s�lectionn�e
+     *    \param      htmlname        Nom de la zone select
+     *    \param      filtretype      Pour filtre
+     */
+    function load_cache_conditions_paiements()
     {
-        dolibarr_print_error($db);
+        global $langs;
+
+        dolibarr_syslog('html.form.class.php::load_cache_conditions_paiements');
+        $sql = "SELECT rowid, libelle";
+        $sql.= " FROM ".MAIN_DB_PREFIX."cond_reglement";
+        $sql.= " WHERE actif=1";
+        $sql.= " ORDER BY sortorder";
+        $resql = $this->db->query($sql);
+        if ($resql)
+        {
+            $num = $this->db->num_rows($result);
+            $i = 0;
+            while ($i < $num)
+            {
+                $obj = $this->db->fetch_object($resql);
+
+                // Si traduction existe, on l'utilise, sinon on prend le libell� par d�faut
+                $libelle=($langs->trans($obj->code)!=$obj->code?$langs->trans($obj->code):($obj->libelle!='-'?$obj->libelle:''));
+                $this->cache_conditions_paiements_code[$obj->rowid]=$obj->code;
+                $this->cache_conditions_paiements_libelle[$obj->rowid]=$libelle;
+                $i++;
+            }
+            return 1;
+        }
+        else {
+            dolibarr_print_error($this->db);
+            return -1;
+        }
     }
-  }
-  
-  
-  /**
-   *    \brief      Retourne la liste des types de paiements possibles
-   *    \param      selected        Type de praiement pr�s�lectionn�
-   *    \param      htmlname        Nom de la zone select
-   *    \param      filtretype      Pour filtre
-   */
-    function select_types_paiements($selected='',$htmlname='paiementtype',$filtertype=-1)
+
+    /**
+     *    \brief      Charge dans cache la liste des types de paiements possibles
+     *    \param      selected        Type de praiement pr�s�lectionn�
+     *    \param      htmlname        Nom de la zone select
+     *    \param      filtretype      Pour filtre
+     */
+    function load_cache_types_paiements()
     {
         global $langs;
-        
-        $sql = "SELECT id, code, libelle";
+
+        dolibarr_syslog('html.form.class.php::load_cache_types_paiements');
+        $sql = "SELECT id, code, libelle, type";
         $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement";
         $sql.= " WHERE active > 0";
-        if ($filtertype >= 0) $sql.=" AND type = $filtertype";
         $sql.= " ORDER BY id";
-        $result = $this->db->query($sql);
-        if ($result)
+        $resql = $this->db->query($sql);
+        if ($resql)
         {
-            print '<select class="flat" name="'.$htmlname.'">';
             $num = $this->db->num_rows($result);
             $i = 0;
             while ($i < $num)
             {
-                $obj = $this->db->fetch_object($result);
-                if ($selected == $obj->code)
-                {
-                    print '<option value="'.$obj->id.'" selected="true">';
-                }
-                else
-                {
-                    print '<option value="'.$obj->id.'">';
-                }
+                $obj = $this->db->fetch_object($resql);
+
                 // Si traduction existe, on l'utilise, sinon on prend le libell� par d�faut
-                print ($langs->trans($obj->code)!=$obj->code?$langs->trans($obj->code):($obj->libelle!='-'?$obj->libelle:''));
-                print '</option>';
+                $libelle=($langs->trans($obj->code)!=$obj->code?$langs->trans($obj->code):($obj->libelle!='-'?$obj->libelle:''));
+                $this->cache_types_paiements_code[$obj->id]=$obj->code;
+                $this->cache_types_paiements_libelle[$obj->id]=$libelle;
+                $this->cache_types_paiements_type[$obj->id]=$obj->type;
                 $i++;
             }
-            print "</select>";
+            return 1;
         }
         else {
             dolibarr_print_error($this->db);
+            return -1;
+        }
+    }
+
+ 
+ 
+     /**
+     *    \brief      Retourne la liste des types de paiements possibles
+     *    \param      selected        Type de praiement pr�s�lectionn�
+     *    \param      htmlname        Nom de la zone select
+     *    \param      filtretype      Pour filtre
+     */
+    function select_conditions_paiements($selected='',$htmlname='condid',$filtertype=-1)
+    {
+        global $langs;
+        
+        // Charge le cache si premier appel
+        if (! sizeof($this->cache_conditions_paiements_code))
+        {
+            $this->load_cache_conditions_paiements();
+        }
+ 
+        print '<select class="flat" name="'.$htmlname.'">';
+        foreach($this->cache_conditions_paiements_code as $id => $code)
+        {
+            if ($selected == $code)
+            {
+                print '<option value="'.$id.'" selected="true">';
+            }
+            else
+            {
+                print '<option value="'.$id.'">';
+            }
+            print $this->cache_conditions_paiements_libelle[$id];
+            print '</option>';
         }
+        print '</select>';
+    }
+
+
+    
+
+    /**
+     *      \brief      Retourne la liste des types de paiements possibles
+     *      \param      selected        Type de praiement pr�s�lectionn�
+     *      \param      htmlname        Nom de la zone select
+     *      \param      filtretype      Pour filtre
+     *      \param      format          0=id+libelle, 1=code+code
+     */
+    function select_types_paiements($selected='',$htmlname='paiementtype',$filtertype='',$format=0)
+    {
+        global $langs;
+
+        $filterarray=array();
+        if ($filtertype && $filtertype != '-1') $filterarray=split(',',$filtertype);
+        
+        // Charge le cache si premier appel
+        if (! sizeof($this->cache_types_paiements_code))
+        {
+            $this->load_cache_types_paiements();
+        }
+
+        //dolibarr_syslog('html.form.class.php::select_types_paiements use cache');
+        print '<select class="flat" name="'.$htmlname.'">';
+        foreach($this->cache_types_paiements_code as $id => $code)
+        {
+            // On passe si on a demand� de filtrer sur des modes de paiments particuli�rs
+            if (sizeof($filterarray) && ! in_array($this->cache_types_paiements_type[$id],$filterarray)) continue;
+
+            if ($format == 0) print '<option value="'.$id.'"';
+            if ($format == 1) print '<option value="'.$code.'"';
+            if ($selected == $code)
+            {
+                print ' selected="true"';
+            }
+            print '>';
+            if ($format == 0) print $this->cache_types_paiements_libelle[$id];
+            if ($format == 1) print $code;
+            print '</option>';
+        }
+        print '</select>';
     }