Browse Source

Merge branch '5.0' of git@github.com:Dolibarr/dolibarr.git into develop

Conflicts:
	htdocs/admin/dict.php
	htdocs/commande/list.php
	htdocs/core/class/html.form.class.php
	htdocs/langs/en_US/bills.lang
	htdocs/societe/list.php
Laurent Destailleur 8 years ago
parent
commit
4c056d68d8

+ 8 - 5
build/debian/control

@@ -10,12 +10,13 @@ Build-Depends: debhelper (>= 9), po-debconf
  
 Package: dolibarr
 Architecture: all
-Depends: libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php,
-    php-cli, 
+# For debian 7 or 8 or 9
+Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5 | libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php,
+    php5-cli | php-cli,
 # Required PHP extensions
-    php-mysql | php-mysqli, php-curl, php-gd, php-ldap,
+    php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd,
 # Required PHP libraries
-    php-pear, php-mail-mime, php-xml, php-mbstring,
+    php-pear, php-mail-mime,
 #    php-tcpdf,
 #    libfpdf-tpl-php, php-fpdf,
 #    libphp-adodb,
@@ -30,7 +31,9 @@ Depends: libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php
     ${misc:Depends},
     ${perl:Depends}
 Recommends: apache2 | lighttpd | httpd,
-    mariadb-server | virtual-mysql-server
+    mariadb-server | virtual-mysql-server,
+# Required PHP extensions for debian 9 but we can't add them into a Depends, it does not exists on debian 7 and 8
+    php-xml, php-mbstring
 Suggests: www-browser, php5-geoip
 Description: Web based software to manage a company or foundation
  Dolibarr ERP & CRM is an easy to use open source/free software package for 

+ 2 - 0
dev/translation/sanity_check_en_langfiles.php

@@ -300,6 +300,8 @@ if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($a
 	    if (preg_match('/^BoxTitleLatest/', $value)) $qualifiedforclean=0;
 	    // install.lang
 	    if (preg_match('/^KeepDefaultValues/', $value)) $qualifiedforclean=0;
+		// mail.lang
+	    if (preg_match('/MailingModuleDesc/i', $value)) $qualifiedforclean=0;
 	    // main.lang
 	    if (preg_match('/^Duration/', $value)) $qualifiedforclean=0;
 	    if (preg_match('/^FormatDate/', $value)) $qualifiedforclean=0;

+ 1 - 1
htdocs/comm/action/card.php

@@ -1324,7 +1324,7 @@ if ($id > 0)
 		print '<div class="assignedtouser">';
 		print $form->select_dolusers_forevent('view', 'assignedtouser', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');
 		print '</div>';
-		if (in_array($user->id,array_keys($listofuserid))) 
+		if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid))) 
 		{
 			print '<div class="myavailability">';
 			print $langs->trans("MyAvailability").': '.(($object->userassigned[$user->id]['transparency'] > 0)?$langs->trans("Busy"):$langs->trans("Available"));	// We show nothing if event is assigned to nobody

+ 6 - 6
htdocs/comm/index.php

@@ -160,10 +160,10 @@ if (! empty($conf->propal->enabled) && $user->rights->propal->lire)
 		print '<tr class="liste_titre">';
 		print '<th colspan="3">'.$langs->trans("ProposalsDraft").($num?' <span class="badge">'.$num.'</span>':'').'</th></tr>';
 
+		$var=true;
 		if ($num > 0)
 		{
 			$i = 0;
-			$var=true;
 			while ($i < $num)
 			{
 				$obj = $db->fetch_object($resql);
@@ -241,10 +241,10 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos
         print '<tr class="liste_titre">';
         print '<th colspan="3">'.$langs->trans("SupplierProposalsDraft").($num?' <span class="badge">'.$num.'</span>':'').'</th></tr>';
 
+        $var=true;
         if ($num > 0)
         {
             $i = 0;
-            $var=true;
             while ($i < $num)
             {
                 $obj = $db->fetch_object($resql);
@@ -320,10 +320,10 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire)
 		print '<tr class="liste_titre">';
 		print '<th colspan="3">'.$langs->trans("DraftOrders").($num?' <span class="badge">'.$num.'</span>':'').'</th></tr>';
 
-		if ($num)
+		$var = true;
+		if ($num > 0)
 		{
 			$i = 0;
-			$var = true;
 			while ($i < $num)
 			{
 				
@@ -401,10 +401,10 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande
         print '<tr class="liste_titre">';
         print '<th colspan="3">'.$langs->trans("DraftSuppliersOrders").($num?' <span class="badge">'.$num.'</span>':'').'</th></tr>';
 
-        if ($num)
+        $var = true;
+        if ($num > 0)
         {
             $i = 0;
-            $var = true;
             while ($i < $num)
             {
                 

+ 4 - 2
htdocs/compta/facture/fiche-rec.php

@@ -996,7 +996,7 @@ if ($action == 'create')
 		// Bank account
 		if ($object->fk_account > 0)
 		{
-			print "<tr><td>".$langs->trans('BankAccount')."</td><td>";
+			print "<tr><td>".$langs->trans('RIB')."</td><td>";
 			$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
 			print "</td></tr>";
 		}
@@ -1266,9 +1266,11 @@ else
 		print '</tr>';
 
 		// Bank Account
+		$langs->load('banks');
+
 		print '<tr><td class="nowrap">';
 		print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
-		print $langs->trans('BankAccount');
+		print $langs->trans('RIB');
 		print '<td>';
 		if (($action != 'editbankaccount') && $user->rights->commande->creer && ! empty($object->brouillon))
 		    print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>';

+ 1 - 1
htdocs/compta/facture/list.php

@@ -506,7 +506,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 	$nbtotalofrecords = $db->num_rows($result);
 }
 
-$sql.= $db->plimit($limit+1,$offset);
+$sql.= $db->plimit($limit,$offset);
 //print $sql;
 
 $resql = $db->query($sql);

+ 2 - 0
htdocs/core/boxes/box_graph_product_distribution.php

@@ -249,6 +249,8 @@ class box_graph_product_distribution extends ModeleBoxes
 
 		if (! empty($conf->commande->enabled) && ! empty($user->rights->commande->lire))
 		{
+			$langs->load("orders");
+			
 			// Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...)
 			if ($showordernb)
 			{

+ 10 - 2
htdocs/core/class/commonobject.class.php

@@ -3162,8 +3162,16 @@ abstract class CommonObject
 		$resql = $this->db->query($sql);
 		if ($resql)
 		{
-			$res = $this->db->fetch_object($resql);
-			return 'Incoterm : '.$res->code.' - '.$this->location_incoterms;
+			$num = $this->db->num_rows($resql);
+			if ($num > 0)
+			{
+				$res = $this->db->fetch_object($resql);
+				return 'Incoterm : '.$res->code.' - '.$this->location_incoterms;
+			}
+			else
+			{
+				return '';
+			}
 		}
 		else
 		{

+ 62 - 52
htdocs/core/class/html.form.class.php

@@ -951,36 +951,40 @@ class Form
     /**
      *  Output html form to select a third party
      *
-     *	@param	string	$selected       Preselected type
-     *	@param  string	$htmlname       Name of field in form
-     *  @param  string	$filter         optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
-     *	@param	string	$showempty		Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
-     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
-     * 	@param	int		$forcecombo		Force to use combo box
-     *  @param	array	$events			Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
-     *	@param	int		$limit			Maximum number of elements
-     *  @param	string	$morecss		Add more css styles to the SELECT component
-     *	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
-     * 	@return	string					HTML string with select box for thirdparty.
+     *	@param	string	$selected       		Preselected type
+     *	@param  string	$htmlname       		Name of field in form
+     *  @param  string	$filter         		optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
+     *	@param	string	$showempty				Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
+     * 	@param	int		$showtype				Show third party type in combolist (customer, prospect or supplier)
+     * 	@param	int		$forcecombo				Force to use combo box
+     *  @param	array	$events					Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
+     *	@param	int		$limit					Maximum number of elements
+     *  @param	string	$morecss				Add more css styles to the SELECT component
+     *	@param  string	$moreparam      		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
+	 *	@param	string	$selected_input_value	Value of preselected input text (for use with ajax)
+     *  @param	int		$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
+     *  @param	array	$ajaxoptions			Options for ajax_autocompleter
+     * 	@return	string							HTML string with select box for thirdparty.
      */
-    function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='')
+    function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array())
     {
+    	global $conf,$user,$langs;
+
     	$out='';
 
-    	/* TODO Use ajax_autocompleter like for products (not finished)
     	if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo)
     	{
     		$placeholder='';
-
     		if ($selected && empty($selected_input_value))
     		{
-    			require_once DOL_DOCUMENT_ROOT.'/societe/ajaxcompanies.php';
-    			$societe = new Societe($this->db);
-    			$societe->fetch($selected);
-    			$selected_input_value=$societe->ref;
+    			require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+    			$societetmp = new Societe($this->db);
+    			$societetmp->fetch($selected);
+    			$selected_input_value=$societetmp->name;
+    			unset($societetmp);
     		}
-    		// mode=1 means customers products
-    		$urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished;
+    		// mode 1
+    		$urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter;
     		print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
     		if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
     		else if ($hidelabel > 1) {
@@ -990,15 +994,15 @@ class Form
     				print img_picto($langs->trans("Search"), 'search');
     			}
     		}
-    		print '<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' />';
+            print '<input type="text" class="minwidth100" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />';
     		if ($hidelabel == 3) {
     			print img_picto($langs->trans("Search"), 'search');
     		}
     	}
     	else
-    	{*/
+    	{
     		$out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam);
-    	//}
+    	}
 
     	return $out;
     }
@@ -1024,7 +1028,8 @@ class Form
     {
         global $conf,$user,$langs;
 
-        $out=''; $num=0;
+        $out=''; 
+        $num=0;
         $outarray=array();
 
         // On recherche les societes
@@ -1040,19 +1045,18 @@ class Form
         if ($filterkey && $filterkey != '')
         {
 			$sql.=" AND (";
-        	if (! empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE))   // Can use index
-        	{
-        		$sql.="(s.name LIKE '".$this->db->escape($filterkey)."%')";
-        	}
-        	else
-        	{
-        		// For natural search
-        		$scrit = explode(' ', $filterkey);
-        		foreach ($scrit as $crit) {
-        			$sql.=" AND (s.name LIKE '%".$this->db->escape($crit)."%')";
-        		}
+        	$prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on
+        	// For natural search
+        	$scrit = explode(' ', $filterkey);
+        	$i=0;
+        	if (count($scrit) > 1) $sql.="(";
+        	foreach ($scrit as $crit) {
+        		if ($i > 0) $sql.=" AND ";
+        		$sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')";
+        		$i++;
         	}
-        	if (! empty($conf->barcode->enabled))
+        	if (count($scrit) > 1) $sql.=")";
+            if (! empty($conf->barcode->enabled))
         	{
         		$sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'";
         	}
@@ -1061,10 +1065,13 @@ class Form
         $sql.=$this->db->order("nom","ASC");
 		if ($limit > 0) $sql.=$this->db->plimit($limit);
 
+		// Build output string
         dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
         $resql=$this->db->query($sql);
         if ($resql)
         {
+			$events = null;
+			
            	if ($conf->use_javascript_ajax && ! $forcecombo)
             {
 				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
@@ -1085,7 +1092,7 @@ class Form
             }
             if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n";
 
-            $num = $this->db->num_rows($resql);
+			$num = $this->db->num_rows($resql);
             $i = 0;
             if ($num)
             {
@@ -1128,7 +1135,7 @@ class Form
                         $out.= '<option value="'.$obj->rowid.'">'.$label.'</option>';
                     }
 
-                    array_push($outarray, array('key'=>$obj->rowid, 'value'=>$obj->rowid, 'label'=>$label));
+                    array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label));
 
                     $i++;
                     if (($i % 10) == 0) $out.="\n";
@@ -3370,11 +3377,14 @@ class Form
             print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
             print '</form>';
         } else {
+
+        	$langs->load('banks');
+
             if ($selected) {
                 require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php';
                 $bankstatic=new Account($this->db);
                 $bankstatic->fetch($selected);
-                print $this->textwithpicto($bankstatic->label,$langs->trans("AccountCurrency").'&nbsp;'.$bankstatic->currency_code);
+                print $this->textwithpicto($bankstatic->getNomUrl(1),$langs->trans("AccountCurrency").'&nbsp;'.$bankstatic->currency_code);
             } else {
                 print "&nbsp;";
             }
@@ -5576,19 +5586,19 @@ class Form
 		$possiblelinks=array();
 		if (is_object($object->thirdparty) && ! empty($object->thirdparty->id) && $object->thirdparty->id > 0)
 		{
-		    $listofidcompanytoscan=$object->thirdparty->id;
-		    if (($object->thirdparty->parent > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO)) $listofidcompanytoscan.=','.$object->thirdparty->parent;
-		    
-		    $possiblelinks=array(
-		        'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')'),
-		        'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.')')
-		    );
+    		$listofidcompanytoscan=$object->thirdparty->id;
+    		if (($object->thirdparty->parent > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO)) $listofidcompanytoscan.=','.$object->thirdparty->parent;
+    		
+    		$possiblelinks=array(
+    		    'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('propal',1).')'),
+    		    'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande',1).')'),
+    		    'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture',1).')'),
+    		    'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract',1).')'),
+    		    'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention',1).')'),
+    		    'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal',1).')'),
+    		    'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur',1).')'),
+    		    'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn',1).')')
+    		);
 		}
 		
 		global $action;

+ 1 - 1
htdocs/core/lib/agenda.lib.php

@@ -118,7 +118,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
 		print '<td class="nowrap" style="padding-bottom: 2px; padding-right: 4px;">';
 		print $langs->trans("ThirdParty").' &nbsp; ';
 		print '</td><td class="nowrap" style="padding-bottom: 2px;">';
-		print $form->select_company($socid, 'socid', '', 1);
+		print $form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0);
 		print '</td></tr>';
 	}
 

+ 0 - 1
htdocs/core/lib/files.lib.php

@@ -1975,7 +1975,6 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 		}
 		$original_file=$conf->expedition->dir_output."/sending/".$original_file;
 	}
-
 	// Wrapping pour les bons de livraison
 	else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output))
 	{

+ 1 - 0
htdocs/core/tpl/ajaxrow.tpl.php

@@ -41,6 +41,7 @@ $(document).ready(function(){
     $(".tdlineupdown").css("background-repeat","no-repeat");
     $(".tdlineupdown").css("background-position","center center");
 
+    console.log("Prepare tableDnd for #<?php echo $tagidfortablednd; ?>");
     $("#<?php echo $tagidfortablednd; ?>").tableDnD({
 		onDrop: function(table, row) {
 			var reloadpage = "<?php echo $forcereloadpage; ?>";

+ 18 - 10
htdocs/fourn/class/fournisseur.commande.class.php

@@ -1508,6 +1508,7 @@ class CommandeFournisseur extends CommonOrder
             $this->line->product_type=$product_type;
             $this->line->remise_percent=$remise_percent;
             $this->line->subprice=$pu_ht;
+            $this->line->rang=$this->rang;
             $this->line->info_bits=$info_bits;
             
             $this->line->vat_src_code=$vat_src_code;
@@ -1957,7 +1958,7 @@ class CommandeFournisseur extends CommonOrder
 		    		}
 
 		    	}
-	    		if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot'))	// Accept to move to rception done, only if status of all line are ok (refuse denied)
+	    		if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot'))	// Accept to move to reception done, only if status of all line are ok (refuse denied)
 	    		{
 	    			$dispatcheddenied=$this->getDispachedLines(2);
 	    			if (count($dispatchedlinearray) > 0)
@@ -1996,7 +1997,8 @@ class CommandeFournisseur extends CommonOrder
                     $result = 0;
                     $old_statut = $this->statut;
                     $this->statut = $statut;
-
+					$this->actionmsg2 = $comment;
+					
                     // Call trigger
                     $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user);
                     if ($result < 0) $error++;
@@ -2819,13 +2821,14 @@ class CommandeFournisseur extends CommonOrder
      *
      * @param 		User 	$user                   User action
      * @param       int     $closeopenorder         Close if received
+     * @param		string	$comment				Comment
      * @return		int		                        <0 if KO, 0 if not applicable, >0 if OK
      */
-    public function calcAndSetStatusDispatch(User $user, $closeopenorder=1) 
+    public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') 
     {
-    	global $conf;
+    	global $conf, $langs;
 
-    	if (! empty($conf->commande->enabled) && ! empty($conf->fournisseur->enabled))
+    	if (! empty($conf->fournisseur->enabled))
     	{
     		require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
 
@@ -2854,14 +2857,18 @@ class CommandeFournisseur extends CommonOrder
     				foreach($this->lines as $line) {
     					$qtywished[$line->fk_product]+=$line->qty;
     				}
+    				
+    				$date_liv = dol_now();
+    				
     				//Compare array
     				$diff_array=array_diff_assoc($qtydelivered,$qtywished);
-    				if (count($diff_array)==0) 
+			
+    				if (count($diff_array)==0) //No diff => mean everythings is received
     				{
-    					//No diff => mean everythings is received
     					if ($closeopenorder)
     					{
-        					$ret=$this->setStatus($user,5);
+        					//$ret=$this->setStatus($user,5);
+    						$ret = $this->Livraison($user, $date_liv, 'tot', $comment);   // GETPOST("type") is 'tot', 'par', 'nev', 'can'
         					if ($ret<0) {
         						return -1;
         					}
@@ -2870,7 +2877,8 @@ class CommandeFournisseur extends CommonOrder
     					else
     					{
     					    //Diff => received partially
-    					    $ret=$this->setStatus($user,4);
+    					    //$ret=$this->setStatus($user,4);
+    						$ret = $this->Livraison($user, $date_liv, 'par', $comment);   // GETPOST("type") is 'tot', 'par', 'nev', 'can'
     					    if ($ret<0) {
     					        return -1;
     					    }
@@ -2880,7 +2888,7 @@ class CommandeFournisseur extends CommonOrder
     				else 
     				{
     					//Diff => received partially
-    					$ret=$this->setStatus($user,4);
+    					$ret = $this->Livraison($user, $date_liv, 'par', $comment);   // GETPOST("type") is 'tot', 'par', 'nev', 'can'
     					if ($ret<0) {
     						return -1;
     					}

+ 6 - 24
htdocs/fourn/commande/dispatch.php

@@ -230,7 +230,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
 	}
 
 	if (! $error) {
-		$result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0);
+		$result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0, GETPOST('comment'));
 		if ($result < 0) {
 			setEventMessages($object->error, $object->errors, 'errors');
 			$error ++;
@@ -340,26 +340,7 @@ if ($id > 0 || ! empty($ref)) {
 	print '<div class="underbanner clearboth"></div>';
 	
 	print '<table class="border" width="100%">';
-/*
-	// Ref
-	print '<tr><td class="titlefield">' . $langs->trans("Ref") . '</td>';
-	print '<td colspan="2">';
-	print $form->showrefnav($object, 'ref', '', 1, 'ref', 'ref');
-	print '</td>';
-	print '</tr>';
-
-	// Fournisseur
-	print '<tr><td>' . $langs->trans("Supplier") . "</td>";
-	print '<td colspan="2">' . $soc->getNomUrl(1, 'supplier') . '</td>';
-	print '</tr>';
 
-	// Statut
-	print '<tr>';
-	print '<td>' . $langs->trans("Status") . '</td>';
-	print '<td colspan="2">';
-	print $object->getLibStatut(4);
-	print "</td></tr>";
-*/
 	// Date
 	if ($object->methode_commande_id > 0) {
 		print '<tr><td class="titlefield">' . $langs->trans("Date") . '</td><td>';
@@ -585,7 +566,8 @@ if ($id > 0 || ! empty($ref)) {
 						} elseif (count($listwarehouses) == 1) {
 							print $formproduct->selectWarehouses(GETPOST("entrepot" . $suffix), "entrepot" . $suffix, '', 0, 0, $objp->fk_product);
 						} else {
-							print $langs->trans("NoWarehouseDefined");
+							$langs->load("errors");
+							print $langs->trans("ErrorNoWarehouseDefined");
 						}
 						print "</td>\n";
 
@@ -609,7 +591,7 @@ if ($id > 0 || ! empty($ref)) {
             
 			print '<br><div class="center">';
             print $langs->trans("Comment") . ' : ';
-			print '<input type="text" class="minwidth200" maxlength="128" name="comment" value="';
+			print '<input type="text" class="minwidth400" maxlength="128" name="comment" value="';
 			print $_POST["comment"] ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
 			// print ' / '.$object->ref_supplier; // Not yet available
 			print '" class="flat"><br>';
@@ -662,7 +644,7 @@ if ($id > 0 || ! empty($ref)) {
 			print '<table class="noborder" width="100%">';
 
 			print '<tr class="liste_titre">';
-			print '<td>' . $langs->trans("Description") . '</td>';
+			print '<td>' . $langs->trans("Product") . '</td>';
 			if (! empty($conf->productbatch->enabled)) {
 				print '<td>' . $langs->trans("batch_number") . '</td>';
 				print '<td>' . $langs->trans("EatByDate") . '</td>';
@@ -705,7 +687,7 @@ if ($id > 0 || ! empty($ref)) {
 				print '</td>';
 
 				// Comment
-				print '<td>' . dol_trunc($objp->comment) . '</td>';
+				print '<td class="tdoverflowmax300">' . $objp->comment . '</td>';
 
 				// Status
 				if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {

+ 13 - 5
htdocs/fourn/facture/card.php

@@ -1117,7 +1117,7 @@ if (empty($reshook))
 	    $action = '';
 	}
 
-	elseif ($action == 'classin')
+	elseif ($action == 'classin' && $user->rights->fournisseur->facture->creer)
 	{
 	    $object->fetch($id);
 	    $result=$object->setProject($projectid);
@@ -2146,7 +2146,9 @@ else
 		print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
 		print $langs->trans('PaymentConditions');
 		print '<td>';
-		if ($action != 'editconditions') print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editconditions&amp;id='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
+		if ($action != 'editconditions' && $user->rights->fournisseur->facture->creer) {
+			print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editconditions&amp;id='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
+		}
 		print '</tr></table>';
 		print '</td><td colspan="2">';
 		if ($action == 'editconditions')
@@ -2166,7 +2168,9 @@ else
 		print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
 		print $langs->trans('PaymentMode');
 		print '</td>';
-		if ($action != 'editmode') print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editmode&amp;id='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
+		if ($action != 'editmode' && $user->rights->fournisseur->facture->creer) {
+			print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editmode&amp;id='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
+		}
 		print '</tr></table>';
 		print '</td><td colspan="2">';
 		if ($action == 'editmode')
@@ -2663,13 +2667,17 @@ else
 	 	 		// Reopen a standard paid invoice
 	            if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT) && ($object->statut == 2 || $object->statut == 3))				// A paid invoice (partially or completely)
 	            {
-	                if (! $facidnext && $object->close_code != 'replaced')	// Not replaced by another invoice
+	                if (! $facidnext && $object->close_code != 'replaced' && $user->rights->fournisseur->facture->creer)	// Not replaced by another invoice
 	                {
 	                    print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=reopen">'.$langs->trans('ReOpen').'</a></div>';
 	                }
 	                else
 	                {
-	                    print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span></div>';
+	                	if ($user->rights->fournisseur->facture->creer) {
+	                        print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span></div>';
+		                } elseif (empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
+			                print '<div class="inline-block divButAction"><span class="butActionRefused">'.$langs->trans('ReOpen').'</span></div>';
+		                }
 	                }
 	            }
 

+ 2 - 2
htdocs/hrm/index.php

@@ -150,7 +150,7 @@ $langs->load("boxes");
 
 
 
-// Last leave requests
+// Latest leave requests
 if (! empty($conf->holiday->enabled) && $user->rights->holiday->read)
 {
     $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.photo, u.statut, x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status";
@@ -206,7 +206,7 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read)
                 $starthalfday=($obj->halfday == -1 || $obj->halfday == 2)?'afternoon':'morning';
                 $endhalfday=($obj->halfday == 1 || $obj->halfday == 2)?'morning':'afternoon';
                 
-                print '<td>'.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$endhalfday]);
+                print '<td>'.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$starthalfday]);
                 print '<td>'.dol_print_date($obj->date_end,'day').' '.$langs->trans($listhalfday[$endhalfday]);
                 print '<td align="right">'.dol_print_date($db->jdate($obj->dm),'day').'</td>';
                 print '<td>'.$holidaystatic->LibStatut($obj->status,3).'</td>';

+ 56 - 20
htdocs/install/repair.php

@@ -74,9 +74,9 @@ print '<h3>'.$langs->trans("Repair").'</h3>';
 
 print 'Option restore_thirdparties_logos is '.(GETPOST('restore_thirdparties_logos')?GETPOST('restore_thirdparties_logos'):'0').'<br>'."\n";
 print 'Option clean_linked_elements is '.(GETPOST('clean_linked_elements')?GETPOST('clean_linked_elements'):'0').'<br>'."\n";
-print 'Option clean_orphelin_dir (1 or confirmed) is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'<br>'."\n";
-print 'Option clean_product_stock_batch (1 or confirmed) is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'<br>'."\n";
-print 'Option set_empty_time_spent_amount (1 or confirmed) is '.(GETPOST('set_empty_time_spent_amount')?GETPOST('set_empty_time_spent_amount'):'0').'<br>'."\n";
+print 'Option clean_orphelin_dir (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'<br>'."\n";
+print 'Option clean_product_stock_batch (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'<br>'."\n";
+print 'Option set_empty_time_spent_amount (0 or \'test\' or \'confirmed\') is '.(GETPOST('set_empty_time_spent_amount')?GETPOST('set_empty_time_spent_amount'):'0').'<br>'."\n";
 print '<br>';
 
 print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
@@ -547,14 +547,17 @@ if ($ok && GETPOST('clean_orphelin_dir'))
 // clean_linked_elements: Check and clean linked elements
 if ($ok && GETPOST('clean_product_stock_batch'))
 {
-    print '<tr><td colspan="2"><br>*** Clean table product_batch</td></tr>';
+    $methodtofix=GETPOST('methodtofix')?GETPOST('methodtofix'):'updatestock';
+    
+    print '<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
     
     $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
-    $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
-    $sql.=" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
+    $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb ON ps.rowid = pb.fk_product_stock";
+    $sql.=" WHERE p.rowid = ps.fk_product";
     $sql.=" AND p.tobatch = 1";
     $sql.=" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
-    $sql.=" HAVING reel != SUM(pb.qty)";
+    $sql.=" HAVING reel != SUM(pb.qty) or SUM(pb.qty) IS NULL";
+    print $sql;
     $resql = $db->query($sql);
     if ($resql)
     {
@@ -566,13 +569,11 @@ if ($ok && GETPOST('clean_product_stock_batch'))
             while ($i < $num)
             {
                 $obj=$db->fetch_object($resql);
-                print '<tr><td>'.$obj->rowid.'-'.$obj->ref.'-'.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' != '.$obj->reelbatch;
+                print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehose '.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' (product_stock.reel) != '.($obj->reelbatch?$obj->reelbatch:'0').' (sum product_batch)';
                 
                 // Fix
                 if ($obj->reel != $obj->reelbatch)
                 {
-                    $methodtofix='updatestock';
-                    
                     if ($methodtofix == 'updatebatch')
                     {
                         // Method 1
@@ -594,7 +595,7 @@ if ($ok && GETPOST('clean_product_stock_batch'))
                     if ($methodtofix == 'updatestock')
                     {
                         // Method 2
-                        print ' -> Update qty of stock with qty = '.$obj->reelbatch.' for ps.rowid = '.$obj->psrowid;
+                        print ' -> Update qty of product_stock with qty = '.($obj->reelbatch?$obj->reelbatch:'0').' for ps.rowid = '.$obj->psrowid;
                         if (GETPOST('clean_product_stock_batch') == 'confirmed')
                         {
                             $error=0;
@@ -602,11 +603,11 @@ if ($ok && GETPOST('clean_product_stock_batch'))
                             $db->begin();
                             
                             $sql2 ="UPDATE ".MAIN_DB_PREFIX."product_stock";
-                            $sql2.=" SET reel = ".$obj->reelbatch." WHERE rowid = ".$obj->psrowid;
+                            $sql2.=" SET reel = ".($obj->reelbatch?$obj->reelbatch:'0')." WHERE rowid = ".$obj->psrowid;
                             $resql2=$db->query($sql2);
                             if ($resql2)
                             {
-                                // We update product stock, so we must update product.stock too.
+                                // We update product_stock, so we must field stock into product too.
                                 $sql3='UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid)';
                                 $resql3=$db->query($sql3);
                                 if (! $resql3) 
@@ -632,6 +633,10 @@ if ($ok && GETPOST('clean_product_stock_batch'))
                 $i++;
             }
         }
+        else
+        {
+            print '<tr><td colspan="2">Nothing to do</td></tr>';
+        }
     }
     else
     {
@@ -640,6 +645,34 @@ if ($ok && GETPOST('clean_product_stock_batch'))
 }
 
 
+// clean_linked_elements: Check and clean linked elements
+if ($ok && GETPOST('clean_product_stock_negative_if_batch'))
+{
+    print '<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
+
+    $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
+    $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
+    $sql.=" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
+    $sql.=" AND p.tobatch = 1";
+    $sql.=" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
+    $sql.=" HAVING reel != SUM(pb.qty)";
+    $resql = $db->query($sql);
+    if ($resql)
+    {
+        $num = $db->num_rows($resql);
+
+        if ($num)
+        {
+            $i = 0;
+            while ($i < $num)
+            {
+                $obj=$db->fetch_object($resql);
+                print '<tr><td>'.$obj->rowid.'-'.$obj->ref.'-'.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' != '.$obj->reelbatch;
+
+            }
+        }
+    }
+}
 
 // clean_linked_elements: Check and clean linked elements
 if ($ok && GETPOST('set_empty_time_spent_amount'))
@@ -667,15 +700,18 @@ if ($ok && GETPOST('set_empty_time_spent_amount'))
 
                 $db->begin();
 
-                $sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time";
-                $sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id;
-                $resql2=$db->query($sql2);
-                if (! $resql2)
+                if (GETPOST('set_empty_time_spent_amount') == 'confirmed')
                 {
-                    $error++;
-                    dol_print_error($db);
+                    $sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time";
+                    $sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id;
+                    $resql2=$db->query($sql2);
+                    if (! $resql2)
+                    {
+                        $error++;
+                        dol_print_error($db);
+                    }
                 }
-
+                
                 if (!$error) $db->commit();
                 else $db->rollback();
 

+ 3 - 11
htdocs/langs/en_US/bills.lang

@@ -126,8 +126,8 @@ BillStatusClosedUnpaid=Closed (unpaid)
 BillStatusClosedPaidPartially=Paid (partially)
 BillShortStatusDraft=Draft
 BillShortStatusPaid=Paid
-BillShortStatusPaidBackOrConverted=Credit note refund/converted
-BillShortStatusConverted=Processed
+BillShortStatusPaidBackOrConverted=Refund or converted
+BillShortStatusConverted=Paid
 BillShortStatusCanceled=Abandoned
 BillShortStatusValidated=Validated
 BillShortStatusStarted=Started
@@ -273,12 +273,8 @@ CreditNotes=Credit notes
 Deposit=Down payment
 Deposits=Down payments
 DiscountFromCreditNote=Discount from credit note %s
-<<<<<<< HEAD
-DiscountFromDeposit=Payments from deposit invoice %s
-DiscountFromExcessReceived=Payments from excess received of invoice %s
-=======
 DiscountFromDeposit=Down payments from invoice %s
->>>>>>> branch '5.0' of git@github.com:Dolibarr/dolibarr.git
+DiscountFromExcessReceived=Payments from excess received of invoice %s
 AbsoluteDiscountUse=This kind of credit can be used on invoice before its validation
 CreditNoteDepositUse=Invoice must be validated to use this kind of credits
 NewGlobalDiscount=New absolute discount
@@ -437,11 +433,7 @@ ChequeDeposits=Checks deposits
 Cheques=Checks
 DepositId=Id deposit
 NbCheque=Number of checks
-<<<<<<< HEAD
 CreditNoteConvertedIntoDiscount=This %s has been converted into %s
-=======
-CreditNoteConvertedIntoDiscount=This credit note or down payment invoice has been converted into %s
->>>>>>> branch '5.0' of git@github.com:Dolibarr/dolibarr.git
 UsBillingContactAsIncoiveRecipientIfExist=Use customer billing contact address instead of third party address as recipient for invoices
 ShowUnpaidAll=Show all unpaid invoices
 ShowUnpaidLateOnly=Show late unpaid invoices only

+ 1 - 0
htdocs/langs/en_US/errors.lang

@@ -185,6 +185,7 @@ ErrorTaskAlreadyAssigned=Task already assigned to user
 ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong format.
 ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (<strong>%s</strong>) does not match expected name syntax: <strong>%s</strong>
 ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s.
+ErrorNoWarehouseDefined=Error, no warehouses defined.
 
 # Warnings
 WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.  

+ 4 - 0
htdocs/langs/en_US/mails.lang

@@ -79,6 +79,10 @@ MailingModuleDescContactsWithThirdpartyFilter=Contact with customer filters
 MailingModuleDescContactsByCompanyCategory=Contacts by third party category
 MailingModuleDescContactsByCategory=Contacts by categories
 MailingModuleDescContactsByFunction=Contacts by position
+MailingModuleDescEmailsFromFile=Emails from file
+MailingModuleDescEmailsFromUser=Emails input by user
+MailingModuleDescDolibarrUsers=Users with Emails
+MailingModuleDescThirdPartiesByCategories=Third parties (by categories)
 
 # Libelle des modules de liste de destinataires mailing
 LineInFile=Line %s in file

+ 3 - 3
htdocs/loan/card.php

@@ -278,7 +278,7 @@ if ($action == 'create')
 	}
 
     // Capital
-    print '<tr><td class="fieldrequired">'.$langs->trans("LoanCapital").'</td><td><input name="capital" size="10" value="' . GETPOST("capital") . '"></td></tr>';
+    print '<tr><td class="fieldrequired">'.$langs->trans("LoanCapital").'</td><td><input name="capital" size="10" value="' . dol_escape_htmltag(GETPOST("capital")) . '"></td></tr>';
 
 	// Date Start
 	print "<tr>";
@@ -293,10 +293,10 @@ if ($action == 'create')
     print '</td></tr>';
 
 	// Number of terms
-	print '<tr><td class="fieldrequired">'.$langs->trans("Nbterms").'</td><td><input name="nbterm" size="5" value="' . GETPOST('nbterm') . '"></td></tr>';
+	print '<tr><td class="fieldrequired">'.$langs->trans("Nbterms").'</td><td><input name="nbterm" size="5" value="' . dol_escape_htmltag(GETPOST('nbterm')) . '"></td></tr>';
 
 	// Rate
-    print '<tr><td class="fieldrequired">'.$langs->trans("Rate").'</td><td><input name="rate" size="5" value="' . GETPOST("rate") . '"> %</td></tr>';
+    print '<tr><td class="fieldrequired">'.$langs->trans("Rate").'</td><td><input name="rate" size="5" value="' . dol_escape_htmltag(GETPOST("rate")) . '"> %</td></tr>';
 
     // Project
     if (! empty($conf->projet->enabled))

+ 1 - 1
htdocs/product/fournisseurs.php

@@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.
 $langs->load("products");
 $langs->load("suppliers");
 $langs->load("bills");
-if (! empty($conf->margin->enabled)) $langs->load("margins");
+$langs->load("margins");
 
 $id = GETPOST('id', 'int');
 $ref = GETPOST('ref', 'alpha');

+ 12 - 20
htdocs/societe/ajax/company.php

@@ -18,8 +18,8 @@
  */
 
 /**
- *       \file       htdocs/product/ajax/company.php
- *       \brief      File to return Ajax response on product list request
+ *       \file       htdocs/societe/ajax/company.php
+ *       \brief      File to return Ajax response on thirdparty list request
  */
 
 if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
@@ -33,15 +33,11 @@ if (empty($_GET['keysearch']) && ! defined('NOREQUIREHTML'))  define('NOREQUIREH
 require '../../main.inc.php';
 
 $htmlname=GETPOST('htmlname','alpha');
-$socid=GETPOST('socid','int');
-$type=GETPOST('type','int');
-$mode=GETPOST('mode','int');
-$status=((GETPOST('status','int') >= 0) ? GETPOST('status','int') : -1);
+$filter=GETPOST('filter','alpha');
 $outjson=(GETPOST('outjson','int') ? GETPOST('outjson','int') : 0);
-$price_level=GETPOST('price_level','int');
 $action=GETPOST('action', 'alpha');
 $id=GETPOST('id', 'int');
-$price_by_qty_rowid=GETPOST('pbq', 'int');
+
 
 /*
  * View
@@ -49,7 +45,7 @@ $price_by_qty_rowid=GETPOST('pbq', 'int');
 
 //print '<!-- Ajax page called with url '.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY_STRING"].' -->'."\n";
 
-dol_syslog(join(',',$_GET));
+dol_syslog(join(',', $_GET));
 //print_r($_GET);
 
 if (! empty($action) && $action == 'fetch' && ! empty($id))
@@ -63,8 +59,11 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
 	if ($ret > 0)
 	{
 		$outname=$object->name;
-
-		$outjson = array('name'=>$outname);
+		$outlabel = '';
+		$outdesc = '';
+		$outtype = $object->type;
+		
+		$outjson = array('ref' => $outref,'name' => $outname,'desc' => $outdesc,'type' => $outtype);
 	}
 
 	echo json_encode($outjson);
@@ -73,7 +72,7 @@ else
 {
 	require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
 
-	$langs->load("products");
+	$langs->load("companies");
 	$langs->load("main");
 
 	top_httphead();
@@ -90,14 +89,7 @@ else
 	$searchkey=(GETPOST($id)?GETPOST($id):(GETPOST($htmlname)?GETPOST($htmlname):''));
 
 	$form = new Form($db);
-	if (empty($mode) || $mode == 'customer')
-	{
-		$arrayresult=$form->select_company_html($socid,$htmlname,"client IN (1,3)",0,0,0,null,$searchkey,$outjson);
-	}
-	elseif ($mode == 'supplier')
-	{
-		$arrayresult=$form->select_company_html($socid,$htmlname,"fournisseur=1",0,0,0,null,$searchkey,$outjson);
-	}
+	$arrayresult=$form->select_thirdparty_list(0,$htmlname,$filter,1,0,0,null,$searchkey,$outjson);
 
 	$db->close();
 

+ 1 - 1
htdocs/societe/list.php

@@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
 require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
 
-$langs->loadLangs(array("companies", "commercial", "customers", "suppliers", "bills", "compta"));
+$langs->loadLangs(array("companies", "commercial", "customers", "suppliers", "bills", "compta", "commercial"));
 
 $action=GETPOST('action','alpha');
 $massaction=GETPOST('massaction','alpha');

+ 1 - 1
htdocs/supplier_proposal/card.php

@@ -1907,7 +1907,7 @@ if ($action == 'create')
 		$formmail->withtocc = $liste;
 		$formmail->withtoccc = (! empty($conf->global->MAIN_EMAIL_USECCC) ? $conf->global->MAIN_EMAIL_USECCC : false);
 
-		$formmail->withtopic = $outputlangs->trans('SendAskRef', '__ASKREF__');
+		$formmail->withtopic = $outputlangs->trans('SendAskRef', '__SUPPLIERPROPREF__');
 
 		$formmail->withfile = 2;
 		$formmail->withbody = 1;

+ 5 - 1
htdocs/user/agenda_extsites.php

@@ -153,7 +153,11 @@ $head=user_prepare_head($object);
 
 dol_fiche_head($head, 'extsites', $langs->trans("User"), -1, 'user');
 
-$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+$linkback = '';
+
+if ($user->rights->user->user->lire || $user->admin) {
+	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+}
 
 dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
 

+ 5 - 1
htdocs/user/bank.php

@@ -133,7 +133,11 @@ if ($id && $action != 'edit')
 	$title = $langs->trans("User");
 	dol_fiche_head($head, 'bank', $title, -1, 'user');
 
-	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	$linkback = '';
+
+	if ($user->rights->user->user->lire || $user->admin) {
+		$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	}
 	
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
         

+ 5 - 1
htdocs/user/card.php

@@ -1202,7 +1202,11 @@ else
 		else
 		{
 			$title = $langs->trans("User");
-			$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+			$linkback = '';
+
+			if ($user->rights->user->user->lire || $user->admin) {
+				$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+			}
 		}
 
         $head = user_prepare_head($object);

+ 5 - 1
htdocs/user/clicktodial.php

@@ -98,7 +98,11 @@ if ($id > 0)
 	
 	dol_fiche_head($head, 'clicktodial', $title, -1, 'user');
 
-	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	$linkback = '';
+
+	if ($user->rights->user->user->lire || $user->admin) {
+		$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	}
 	
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
 	

+ 5 - 2
htdocs/user/document.php

@@ -131,8 +131,11 @@ if ($object->id)
 
 	dol_fiche_head($head, 'document', $langs->trans("User"), -1, 'user');
 
-	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
-
+	$linkback = '';
+	if ($user->rights->user->user->lire || $user->admin) {
+		$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	}
+	
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
 
     print '<div class="fichecenter">';

+ 5 - 1
htdocs/user/info.php

@@ -68,7 +68,11 @@ $title = $langs->trans("User");
 dol_fiche_head($head, 'info', $title, -1, 'user');
 
 
-$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+$linkback = '';
+
+if ($user->rights->user->user->lire || $user->admin) {
+	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+}
 
 dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin);
 

+ 5 - 1
htdocs/user/ldap.php

@@ -96,7 +96,11 @@ $head = user_prepare_head($object);
 $title = $langs->trans("User");
 dol_fiche_head($head, 'ldap', $title, 0, 'user');
 
-$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+$linkback = '';
+
+if ($user->rights->user->user->lire || $user->admin) {
+	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+}
 
 dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
 

+ 5 - 1
htdocs/user/note.php

@@ -90,7 +90,11 @@ if ($id)
 	$title = $langs->trans("User");
 	dol_fiche_head($head, 'note', $title, -1, 'user');
 
-	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	$linkback = '';
+
+	if ($user->rights->user->user->lire || $user->admin) {
+		$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	}
 	
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     

+ 6 - 2
htdocs/user/param_ihm.php

@@ -182,8 +182,12 @@ if ($action == 'edit')
 if ($action == 'edit')
 {
     dol_fiche_head($head, 'guisetup', $title, 0, 'user');
-    
-    $linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+
+	$linkback = '';
+
+	if ($user->rights->user->user->lire || $user->admin) {
+		$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+	}
     
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     

+ 5 - 1
htdocs/user/perms.php

@@ -257,7 +257,11 @@ else
  * Ecran ajout/suppression permission
  */
 
-$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+$linkback = '';
+
+if ($user->rights->user->user->lire || $user->admin) {
+	$linkback = '<a href="'.DOL_URL_ROOT.'/user/index.php">'.$langs->trans("BackToList").'</a>';
+}
 
 dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);