From 60a54041c20f8ac0cb5c7822a1cc0e4f0a105985 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Fri, 7 Apr 2017 14:09:19 +0200
Subject: [PATCH] NEW Enable bulk actions delete on supplier invoices

---
 htdocs/comm/propal/list.php                   |   7 +-
 htdocs/commande/list.php                      |   8 +-
 htdocs/compta/facture/list.php                |  33 +--
 htdocs/core/class/html.formfile.class.php     |   8 +-
 htdocs/core/lib/functions.lib.php             |   2 +-
 .../class/api_supplier_invoices.class.php     |   2 +-
 .../class/fournisseur.commande.class.php      |  25 +-
 .../fourn/class/fournisseur.facture.class.php |  62 ++--
 htdocs/fourn/class/paiementfourn.class.php    |   2 +-
 htdocs/fourn/facture/list.php                 | 274 ++++++++++++++----
 htdocs/main.inc.php                           |   2 +-
 htdocs/theme/eldy/style.css.php               |   6 +
 htdocs/theme/md/style.css.php                 |   6 +
 13 files changed, 304 insertions(+), 133 deletions(-)

diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
index d1ccf6547ce..c06ea117d01 100644
--- a/htdocs/comm/propal/list.php
+++ b/htdocs/comm/propal/list.php
@@ -556,7 +556,8 @@ if ($resql)
 
     $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
     $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
-	
+    if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
+    
     print '<div class="div-table-responsive">';
 	print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
 
@@ -695,7 +696,7 @@ if ($resql)
 	}
 	// Action column
 	print '<td class="liste_titre" align="middle">';
-	$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
+	$searchpitco=$form->showFilterButtons();
 	print $searchpitco;
 	print '</td>';
 	
@@ -807,7 +808,7 @@ if ($resql)
 		// Thirdparty
 		if (! empty($arrayfields['s.nom']['checked']))
 		{
-    		print '<td>';
+    		print '<td class="tdoverflowmax200">';
     		print $companystatic->getNomUrl(1,'customer');
     		print '</td>';
     		if (! $i) $totalarray['nbfield']++;
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index fa94541cdbf..27033254dba 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -789,7 +789,6 @@ if ($resql)
 		print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
 		print '</div>';
 		print '<br>';
-		
 	}
 	
 	if ($sall)
@@ -841,7 +840,8 @@ if ($resql)
 
     $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
     $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
-	
+    if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
+    
     print '<div class="div-table-responsive">';
     print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
 
@@ -992,7 +992,7 @@ if ($resql)
 	}
 	// Action column
 	print '<td class="liste_titre" align="middle">';
-	$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
+	$searchpitco=$form->showFilterButtons();
 	print $searchpitco;
 	print '</td>';
 	
@@ -1222,7 +1222,7 @@ if ($resql)
 		// Third party
 		if (! empty($arrayfields['s.nom']['checked']))
 		{
-    		print '<td>';
+    		print '<td class="tdoverflowmax200">';
     		print $companystatic->getNomUrl(1,'customer');
     
     		// If module invoices enabled and user with invoice creation permissions
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 03612cbb932..92fcf4fc511 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -738,7 +738,8 @@ if ($resql)
 
     $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
     $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
-
+    if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
+    
     print '<div class="div-table-responsive">';
     print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
 
@@ -748,14 +749,14 @@ if ($resql)
 	if (! empty($arrayfields['f.facnumber']['checked'])) 
 	{
         print '<td class="liste_titre" align="left">';
-        print '<input class="flat" size="6" type="text" name="search_ref" value="'.$search_ref.'">';
+        print '<input class="flat" size="6" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
         print '</td>';
 	}
 	// Ref customer
 	if (! empty($arrayfields['f.ref_client']['checked'])) 
 	{
     	print '<td class="liste_titre">';
-    	print '<input class="flat" size="6" type="text" name="search_refcustomer" value="'.$search_refcustomer.'">';
+    	print '<input class="flat" size="6" type="text" name="search_refcustomer" value="'.dol_escape_htmltag($search_refcustomer).'">';
     	print '</td>';
 	}
 	// Type
@@ -776,8 +777,8 @@ if ($resql)
 	if (! empty($arrayfields['f.date']['checked'])) 
 	{
     	print '<td class="liste_titre" align="center">';
-        if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day" value="'.$day.'">';
-        print '<input class="flat" type="text" size="1" maxlength="2" name="month" value="'.$month.'">';
+        if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day" value="'.dol_escape_htmltag($day).'">';
+        print '<input class="flat" type="text" size="1" maxlength="2" name="month" value="'.dol_escape_htmltag($month).'">';
         $formother->select_year($year?$year:-1,'year',1, 20, 5);
         print '</td>';
 	}
@@ -785,8 +786,8 @@ if ($resql)
 	if (! empty($arrayfields['f.date_lim_reglement']['checked'])) 
 	{
     	print '<td class="liste_titre" align="center">';
-        if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day_lim" value="'.$day_lim.'">';
-        print '<input class="flat" type="text" size="1" maxlength="2" name="month_lim" value="'.$month_lim.'">';
+        if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day_lim" value="'.dol_escape_htmltag($day_lim).'">';
+        print '<input class="flat" type="text" size="1" maxlength="2" name="month_lim" value="'.dol_escape_htmltag($month_lim).'">';
         $formother->select_year($year_lim?$year_lim:-1,'year_lim',1, 20, 5);
     	print '<br><input type="checkbox" name="option" value="late"'.($option == 'late'?' checked':'').'> '.$langs->trans("Late");
         print '</td>';
@@ -797,9 +798,9 @@ if ($resql)
 	   print '<td class="liste_titre" align="left"><input class="flat" type="text" size="6" name="search_societe" value="'.$search_societe.'"></td>';
 	}
 	// Town
-	if (! empty($arrayfields['s.town']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" size="6" name="search_town" value="'.$search_town.'"></td>';
+	if (! empty($arrayfields['s.town']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" size="6" name="search_town" value="'.dol_escape_htmltag($search_town).'"></td>';
 	// Zip
-	if (! empty($arrayfields['s.zip']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" size="4" name="search_zip" value="'.$search_zip.'"></td>';
+	if (! empty($arrayfields['s.zip']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" size="4" name="search_zip" value="'.dol_escape_htmltag($search_zip).'"></td>';
 	// State
 	if (! empty($arrayfields['state.nom']['checked']))
 	{
@@ -832,21 +833,21 @@ if ($resql)
 	{
     	// Amount
     	print '<td class="liste_titre" align="right">';
-    	print '<input class="flat" type="text" size="5" name="search_montant_ht" value="'.$search_montant_ht.'">';
+    	print '<input class="flat" type="text" size="5" name="search_montant_ht" value="'.dol_escape_htmltag($search_montant_ht).'">';
     	print '</td>';
 	}
 	if (! empty($arrayfields['f.total_vat']['checked']))
 	{
     	// Amount
     	print '<td class="liste_titre" align="right">';
-    	print '<input class="flat" type="text" size="5" name="search_montant_vat" value="'.$search_montant_vat.'">';
+    	print '<input class="flat" type="text" size="5" name="search_montant_vat" value="'.dol_escape_htmltag($search_montant_vat).'">';
     	print '</td>';
 	}
 	if (! empty($arrayfields['f.total_ttc']['checked']))
 	{
     	// Amount
     	print '<td class="liste_titre" align="right">';
-    	print '<input class="flat" type="text" size="5" name="search_montant_ttc" value="'.$search_montant_ttc.'">';
+    	print '<input class="flat" type="text" size="5" name="search_montant_ttc" value="'.dol_escape_htmltag($search_montant_ttc).'">';
     	print '</td>';
 	}
     if (! empty($arrayfields['dynamount_payed']['checked']))
@@ -908,7 +909,7 @@ if ($resql)
 	}
 	// Action column
 	print '<td class="liste_titre" align="middle">';
-	$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
+	$searchpitco=$form->showFilterButtons();
 	print $searchpitco;
     print '</td>';
     print "</tr>\n";
@@ -956,12 +957,10 @@ if ($resql)
     if ($num > 0)
     {
         $i=0;
-        $var=true;
         $totalarray=array();
         while ($i < min($num,$limit))
         {
             $obj = $db->fetch_object($resql);
-            $var=!$var;
 
             $datelimit=$db->jdate($obj->datelimite);
             $facturestatic->id=$obj->facid;
@@ -978,7 +977,7 @@ if ($resql)
             $totalpay = $paiement + $totalcreditnotes + $totaldeposits;
             $remaintopay = $obj->total_ttc - $totalpay;
             
-            print '<tr '.$bc[$var].'>';
+            print '<tr class="oddeven">';
     		if (! empty($arrayfields['f.facnumber']['checked']))
     		{
                 print '<td class="nowrap">';
@@ -1045,7 +1044,7 @@ if ($resql)
     		// Third party
     		if (! empty($arrayfields['s.nom']['checked']))
     		{
-                print '<td>';
+                print '<td class="tdoverflowmax200">';
                 $thirdparty=new Societe($db);
                 $thirdparty->id=$obj->socid;
                 $thirdparty->name=$obj->name;
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 647d0cf6a76..73e854248fe 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -871,8 +871,12 @@ class FormFile
     			else $this->infofiles['extensions'][$ext]++;
 
     			// Preview
-    			$urladvanced = getAdvancedPreviewUrl($modulepart, $relativepath);
-    		    if ($urladvanced) $tmpout.= '<li><a href="'.$urladvanced.'">'.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'</a></li>';
+    			if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone'))
+    			{
+                    $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1);
+                    if ($tmparray && $tmparray['url']) $tmpout.= '<li><a href="'.$tmparray['url'].'"'.($tmparray['css']?' class="'.$tmparray['css'].'"':'').($tmparray['mime']?' mime="'.$tmparray['mime'].'"':'').($tmparray['target']?' target="'.$tmparray['target'].'"':'').'>'.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'</a></li>';
+    			}
+    			
     			// Download
     		    $tmpout.= '<li><a class="pictopreview" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).'"';
     			$mime=dol_mimetype($relativepath,'',0);
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 7c428968c34..df3dac377a4 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -5913,7 +5913,7 @@ function getImageFileNameForSize($file, $extName, $extImgTarget='')
  *
  * @param   string    $modulepart     propal, facture, facture_fourn, ...
  * @param   string    $relativepath   Relative path of docs.
- * @param	int		  $alldata		  Return array with all components (1 is recommended)  
+ * @param	int		  $alldata		  Return array with all components (1 is recommended, then use a simple a href link with the class, target and mime attribute added. 'documentpreview' css class is handled by jquery code into main.inc.php)  
  * @return  string|array              Output string with href link or array with all components of link
  */
 function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0)
diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php
index 59e9db1324d..3bf5c3f5934 100644
--- a/htdocs/fourn/class/api_supplier_invoices.class.php
+++ b/htdocs/fourn/class/api_supplier_invoices.class.php
@@ -262,7 +262,7 @@ class SupplierInvoices extends DolibarrApi
 			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
 		}
         
-        if( $this->invoice->delete($id) < 0)
+        if( $this->invoice->delete(DolibarrApiAccess::$user) < 0)
         {
             throw new RestException(500);
         }
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index 1da9854791b..7b732dd05a6 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -1724,27 +1724,30 @@ class CommandeFournisseur extends CommonOrder
      *  Delete an order
      *
      *	@param	User	$user		Object user
+     *	@param	int		$notrigger	1=Does not execute triggers, 0= execute triggers
      *	@return	int					<0 if KO, >0 if OK
      */
-    public function delete($user='')
+    public function delete(User $user, $notrigger=0)
     {
         global $langs,$conf;
         require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
         $error = 0;
 
-        // Call trigger
-        $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user);
-        if ($result < 0)
+        $this->db->begin();
+
+        if (empty($notrigger))
         {
-        	$this->errors[]='ErrorWhenRunningTrigger';
-        	dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
-        	return -1;
+            // Call trigger
+            $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user);
+            if ($result < 0)
+            {
+            	$this->errors[]='ErrorWhenRunningTrigger';
+            	dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+            	return -1;
+            }
+            // End call triggers
         }
-        // End call triggers
-
-
-        $this->db->begin();
 
         $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =". $this->id ;
         dol_syslog(get_class($this)."::delete", LOG_DEBUG);
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 5f435da9daf..42daafe9c2d 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -849,14 +849,15 @@ class FactureFournisseur extends CommonInvoice
     /**
      *	Delete invoice from database
      *
-     *	@param     	int		$rowid      	Id of invoice to delete
+     *  @param      User	$user		    User object
+     *	@param	    int		$notrigger	    1=Does not execute triggers, 0= execute triggers
      *	@return		int						<0 if KO, >0 if OK
      */
-    public function delete($rowid)
+    public function delete(User $user, $notrigger=0)
     {
-        global $user,$langs,$conf;
+        global $langs,$conf;
 
-        if (! $rowid) $rowid=$this->id;
+        $rowid=$this->id;
 
         dol_syslog("FactureFournisseur::delete rowid=".$rowid, LOG_DEBUG);
 
@@ -865,22 +866,37 @@ class FactureFournisseur extends CommonInvoice
         $error=0;
         $this->db->begin();
 
-        $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';';
-        dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-        $resql = $this->db->query($sql);
-        if ($resql)
+        if (! $error && ! $notrigger)
         {
-            $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid;
+            // Call trigger
+            $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user);
+            if ($result < 0)
+            {
+                $this->db->rollback();
+                return -1;
+            }
+            // Fin appel triggers
+        }
+        
+        if (! $error)
+        {
+            $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';';
             dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-            $resql2 = $this->db->query($sql);
-            if (! $resql2) {
+            $resql = $this->db->query($sql);
+            if ($resql)
+            {
+                $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid;
+                dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+                $resql2 = $this->db->query($sql);
+                if (! $resql2) {
+                	$error++;
+                }
+            }
+            else {
             	$error++;
             }
         }
-        else {
-        	$error++;
-        }
-
+        
 		if (! $error)
 		{
 			// Delete linked object
@@ -888,18 +904,6 @@ class FactureFournisseur extends CommonInvoice
 			if ($res < 0) $error++;
 		}
 
-        if (! $error)
-        {
-            // Call trigger
-            $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user);
-            if ($result < 0)
-            {
-        		$this->db->rollback();
-        	    return -1;
-        	}
-        	// Fin appel triggers
-        }
-
         if (! $error)
         {
         	// Delete linked object
@@ -2452,13 +2456,11 @@ class SupplierInvoiceLine extends CommonObjectLine
 	/**
 	 * Deletes a line
 	 *
-	 * @param     bool|int    $notrigger    1=Does not execute triggers, 0= execute triggers
+	 * @param     bool|int   $notrigger     1=Does not execute triggers, 0= execute triggers
 	 * @return    int                       0 if KO, 1 if OK
 	 */
 	public function delete($notrigger = 0)
 	{
-		global $user;
-
 		dol_syslog(get_class($this)."::deleteline rowid=".$this->id, LOG_DEBUG);
 
 		$error = 0;
diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php
index be87fbc7512..12fccab91d8 100644
--- a/htdocs/fourn/class/paiementfourn.class.php
+++ b/htdocs/fourn/class/paiementfourn.class.php
@@ -349,7 +349,7 @@ class PaiementFourn extends Paiement
     			$result=$accline->fetch($bank_line_id);
     			if ($result > 0) // If result = 0, record not found, we don't try to delete
     			{
-    				$result=$accline->delete();
+    				$result=$accline->delete($user);
     			}
     			if ($result < 0)
     			{
diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
index 52320ec9580..1eb2dfaeb4a 100644
--- a/htdocs/fourn/facture/list.php
+++ b/htdocs/fourn/facture/list.php
@@ -48,6 +48,12 @@ $langs->load("companies");
 $langs->load('products');
 $langs->load('projects');
 
+$action=GETPOST('action','alpha');
+$massaction=GETPOST('massaction','alpha');
+$show_files=GETPOST('show_files','int');
+$confirm=GETPOST('confirm','alpha');
+$toselect = GETPOST('toselect', 'array');
+
 $socid = GETPOST('socid','int');
 
 // Security check
@@ -110,7 +116,7 @@ if (! $sortfield) $sortfield="f.datef,f.rowid";
 // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
 $contextpage='supplierinvoicelist';
 
-$diroutputmassaction=$conf->facture->dir_output . '/temp/massgeneration/'.$user->id;
+$diroutputmassaction=$conf->fournisseur->facture->dir_output . '/temp/massgeneration/'.$user->id;
 
 $object=new FactureFournisseur($db);
 
@@ -171,67 +177,62 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
  */
 
 if (GETPOST('cancel')) { $action='list'; $massaction=''; }
-if (! GETPOST('confirmmassaction')) { $massaction=''; }
+if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { $massaction=''; }
 
 $parameters=array('socid'=>$socid);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
-
-if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x"))		// All test must be present to be compatible with all browsers
-{
-    $search_all="";
-    $search_user='';
-    $search_sale='';
-    $search_product_category='';
-    $search_ref="";
-    $search_refsupplier="";
-    $search_label="";
-    $search_project='';
-    $search_societe="";
-    $search_company="";
-    $search_amount_no_tax="";
-    $search_amount_all_tax="";
-    $search_montant_ht='';
-    $search_montant_vat='';
-    $search_montant_ttc='';
-    $search_status='';
-    $search_paymentmode='';
-    $search_town='';
-    $search_zip="";
-    $search_state="";
-    $search_type='';
-    $search_country='';
-    $search_type_thirdparty='';
-    $year="";
-    $month="";
-    $day="";
-    $year_lim="";
-    $month_lim="";
-    $day_lim="";
-    $search_array_options=array();
-    $filter='';
-    $option='';
-}
-
 if (empty($reshook))
 {
-    // Mass actions. Controls on number of lines checked
-    $maxformassaction=1000;
-    if (! empty($massaction) && count($toselect) < 1)
-    {
-        $error++;
-        setEventMessages($langs->trans("NoLineChecked"), null, "warnings");
-    }
-    if (! $error && count($toselect) > $maxformassaction)
+    include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
+    
+    if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x"))		// All test must be present to be compatible with all browsers
     {
-        setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors');
-        $error++;
+        $search_all="";
+        $search_user='';
+        $search_sale='';
+        $search_product_category='';
+        $search_ref="";
+        $search_refsupplier="";
+        $search_label="";
+        $search_project='';
+        $search_societe="";
+        $search_company="";
+        $search_amount_no_tax="";
+        $search_amount_all_tax="";
+        $search_montant_ht='';
+        $search_montant_vat='';
+        $search_montant_ttc='';
+        $search_status='';
+        $search_paymentmode='';
+        $search_town='';
+        $search_zip="";
+        $search_state="";
+        $search_type='';
+        $search_country='';
+        $search_type_thirdparty='';
+        $year="";
+        $month="";
+        $day="";
+        $year_lim="";
+        $month_lim="";
+        $day_lim="";
+        $toselect='';
+        $search_array_options=array();
+        $filter='';
+        $option='';
     }
-
-
+    
+    // Mass actions
+    $objectclass='FactureFournisseur';
+    $objectlabel='SupplierInvoices';
+    $permtoread = $user->rights->fournisseur->facture->lire;
+    $permtodelete = $user->rights->fournisseur->facture->supprimer;
+    $uploaddir = $conf->fournisseur->facture->dir_output;
+    include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
 }
+
     
 /*
  * View
@@ -424,7 +425,15 @@ if ($resql)
 	    if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
 	}
 	
-	$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge")));
+	// List of mass actions available
+	$arrayofmassactions =  array(
+	    //'presend'=>$langs->trans("SendByMail"),
+	    //'builddoc'=>$langs->trans("PDFMerge"),
+	);
+	//if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
+	if ($user->rights->fournisseur->facture->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete");
+	//if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array();
+	$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
 	
 	$i = 0;
 	print '<form method="POST" name="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
@@ -437,7 +446,144 @@ if ($resql)
 	print '<input type="hidden" name="viewstatut" value="'.$viewstatut.'">';
 	print '<input type="hidden" name="socid" value="'.$socid.'">';
 
-	print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
+	print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
+	
+	if ($massaction == 'presend')
+	{
+	    $langs->load("mails");
+	
+	    if (! GETPOST('cancel'))
+	    {
+	        $objecttmp=new Commande($db);
+	        $listofselectedid=array();
+	        $listofselectedthirdparties=array();
+	        $listofselectedref=array();
+	        foreach($arrayofselected as $toselectid)
+	        {
+	            $result=$objecttmp->fetch($toselectid);
+	            if ($result > 0)
+	            {
+	                $listofselectedid[$toselectid]=$toselectid;
+	                $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
+	                $listofselectedthirdparties[$thirdpartyid]=$thirdpartyid;
+	                $listofselectedref[$thirdpartyid][$toselectid]=$objecttmp->ref;
+	            }
+	        }
+	    }
+	
+	    print '<input type="hidden" name="massaction" value="confirm_presend">';
+	
+	    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+	    $formmail = new FormMail($db);
+	
+	    dol_fiche_head(null, '', '');
+	
+	    $topicmail="SendOrderRef";
+	    $modelmail="order_send";
+	
+	    // Cree l'objet formulaire mail
+	    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+	    $formmail = new FormMail($db);
+	    $formmail->withform=-1;
+	    $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user'));
+	
+	    if($formmail->fromtype === 'user'){
+	        $formmail->fromid = $user->id;
+	
+	    }
+	    if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1))	// If bit 1 is set
+	    {
+	        $formmail->trackid='ord'.$object->id;
+	    }
+	    if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2))	// If bit 2 is set
+	    {
+	        include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+	        $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id);
+	    }
+	    $formmail->withfrom=1;
+	    $liste=$langs->trans("AllRecipientSelected");
+	    if (count($listofselectedthirdparties) == 1)
+	    {
+	        $liste=array();
+	        $thirdpartyid=array_shift($listofselectedthirdparties);
+	        $soc=new Societe($db);
+	        $soc->fetch($thirdpartyid);
+	        foreach ($soc->thirdparty_and_contact_email_array(1) as $key=>$value)
+	        {
+	            $liste[$key]=$value;
+	        }
+	        $formmail->withtoreadonly=0;
+	    }
+	    else
+	    {
+	        $formmail->withtoreadonly=1;
+	    }
+	    $formmail->withto=$liste;
+	    $formmail->withtofree=0;
+	    $formmail->withtocc=1;
+	    $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
+	    $formmail->withtopic=$langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__');
+	    $formmail->withfile=$langs->trans("OnlyPDFattachmentSupported");
+	    $formmail->withbody=1;
+	    $formmail->withdeliveryreceipt=1;
+	    $formmail->withcancel=1;
+	    // Tableau des substitutions
+	    $formmail->substit['__REF__']='__REF__';	// We want to keep the tag
+	    $formmail->substit['__SIGNATURE__']=$user->signature;
+	    $formmail->substit['__REFCLIENT__']='__REFCLIENT__';	// We want to keep the tag
+	    $formmail->substit['__PERSONALIZED__']='';
+	    $formmail->substit['__CONTACTCIVNAME__']='';
+	
+	    // Tableau des parametres complementaires du post
+	    $formmail->param['action']=$action;
+	    $formmail->param['models']=$modelmail;
+	    $formmail->param['models_id']=GETPOST('modelmailselected','int');
+	    $formmail->param['id']=join(',',$arrayofselected);
+	    //$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
+	
+	    print $formmail->get_form();
+	
+	    dol_fiche_end();
+	}
+	elseif ($massaction == 'createbills')
+	{
+	    //var_dump($_REQUEST);
+	    print '<input type="hidden" name="massaction" value="confirm_createbills">';
+	
+	    print '<table class="border" width="100%" >';
+	    print '<tr>';
+	    print '<td class="titlefieldmiddle">';
+	    print $langs->trans('DateInvoice');
+	    print '</td>';
+	    print '<td>';
+	    print $form->select_date('', '', '', '', '', '', 1, 1);
+	    print '</td>';
+	    print '</tr>';
+	    print '<tr>';
+	    print '<td>';
+	    print $langs->trans('CreateOneBillByThird');
+	    print '</td>';
+	    print '<td>';
+	    print $form->selectyesno('createbills_onebythird', '', 1);
+	    print '</td>';
+	    print '</tr>';
+	    print '<tr>';
+	    print '<td>';
+	    print $langs->trans('ValidateInvoices');
+	    print '</td>';
+	    print '<td>';
+	    print $form->selectyesno('valdate_invoices', 1, 1);
+	    print '</td>';
+	    print '</tr>';
+	    print '</table>';
+	
+	    print '<br>';
+	    print '<div class="center">';
+	    print '<input type="submit" class="button" id="createbills" name="createbills" value="'.$langs->trans('CreateInvoiceForThisCustomer').'">  ';
+	    print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
+	    print '</div>';
+	    print '<br>';
+	}
 	
 	if ($search_all)
     {
@@ -487,11 +633,11 @@ if ($resql)
 
     $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
     $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
-	
+    if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
+    
     print '<div class="div-table-responsive">';
     print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
 
-
 	// Line for filters
 	print '<tr class="liste_titre_filter">';
 	// Ref
@@ -646,7 +792,7 @@ if ($resql)
 	}
 	// Action column
 	print '<td class="liste_titre" align="middle">';
-	$searchpitco=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 0);
+	$searchpitco=$form->showFilterButtons('checkforselect', 0);
 	print $searchpitco;
 	print '</td>';
 
@@ -688,7 +834,7 @@ if ($resql)
 	if (! empty($arrayfields['f.datec']['checked']))     print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
 	if (! empty($arrayfields['f.tms']['checked']))       print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
 	if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder);
-	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch ');
+	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
 	print "</tr>\n";	
 	
     $facturestatic=new FactureFournisseur($db);
@@ -944,11 +1090,15 @@ if ($resql)
             }
             
     		// Action column
+            // Action column
             print '<td class="nowrap" align="center">';
-            $selected=0;
-    		if (in_array($obj->facid, $arrayofselected)) $selected=1;
-    		//print '<input id="cb'.$obj->facid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->facid.'"'.($selected?' checked="checked"':'').'>';
-    		print '</td>' ;
+            if ($massactionbutton || $massaction)   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
+            {
+                $selected=0;
+                if (in_array($obj->facid, $arrayofselected)) $selected=1;
+                print '<input id="cb'.$obj->facid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->facid.'"'.($selected?' checked="checked"':'').'>';
+            }
+            print '</td>';
     		if (! $i) $totalarray['nbfield']++;
     		
 			print "</tr>\n";
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index f44f2f70acf..8fe2125251c 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -1922,7 +1922,7 @@ if (! function_exists("llxFooter"))
         }
         
         // Wrapper to manage document_preview
-        if (! empty($conf->use_javascript_ajax))
+        if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone'))
         {
             print "\n<!-- JS CODE TO ENABLE document_preview -->\n";
             print '<script type="text/javascript">
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index 77c779b268e..38d50962086 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -624,6 +624,12 @@ div.myavailability {
     text-overflow: ellipsis;
     white-space: nowrap;
 }
+.tdoverflowmax200 {			/* For tdoverflow, the max-midth become a minimum ! */
+    max-width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
 .tdoverflowmax300 {			/* For tdoverflow, the max-midth become a minimum ! */
     max-width: 300px;
     overflow: hidden;
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index 553d2560790..f3232b31d6b 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -625,6 +625,12 @@ div.myavailability {
     text-overflow: ellipsis;
     white-space: nowrap;
 }
+.tdoverflowmax200 {			/* For tdoverflow, the max-midth become a minimum ! */
+    max-width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
 .tdoverflowmax300 {
     max-width: 300px;
     overflow: hidden;
-- 
GitLab