Преглед изворни кода

Merge remote-tracking branch 'origin/3.9' into develop

Conflicts:
	htdocs/core/menus/standard/eldy.lib.php
	htdocs/expedition/card.php
Laurent Destailleur пре 9 година
родитељ
комит
7aaae143fc
34 измењених фајлова са 336 додато и 225 уклоњено
  1. 6 4
      build/makepack-dolibarr.pl
  2. 1 0
      htdocs/accountancy/journal/purchasesjournal.php
  3. 1 1
      htdocs/adherents/list.php
  4. 22 9
      htdocs/admin/confexped.php
  5. 7 6
      htdocs/admin/delais.php
  6. 48 47
      htdocs/admin/dict.php
  7. 5 4
      htdocs/admin/oauth.php
  8. 9 6
      htdocs/comm/mailing/card.php
  9. 3 2
      htdocs/comm/propal.php
  10. 1 0
      htdocs/comm/propal/class/propal.class.php
  11. 4 2
      htdocs/comm/remise.php
  12. 9 6
      htdocs/compta/facture.php
  13. 4 2
      htdocs/core/class/commonobject.class.php
  14. 25 24
      htdocs/core/class/extrafields.class.php
  15. 14 9
      htdocs/core/class/html.form.class.php
  16. 11 5
      htdocs/core/class/html.formcompany.class.php
  17. 23 9
      htdocs/core/lib/ajax.lib.php
  18. 11 10
      htdocs/core/lib/files.lib.php
  19. 4 3
      htdocs/core/lib/functions.lib.php
  20. 2 2
      htdocs/core/lib/functions2.lib.php
  21. 10 2
      htdocs/core/modules/modExpedition.class.php
  22. 2 2
      htdocs/core/modules/modOauth.class.php
  23. 5 1
      htdocs/core/modules/modSociete.class.php
  24. 1 1
      htdocs/core/modules/oauth/google_oauthcallback.php
  25. 8 8
      htdocs/core/modules/printing/printgcp.modules.php
  26. 18 14
      htdocs/expedition/card.php
  27. 29 7
      htdocs/expedition/class/expedition.class.php
  28. 6 5
      htdocs/exports/class/export.class.php
  29. 4 3
      htdocs/imports/class/import.class.php
  30. 3 3
      htdocs/install/mysql/migration/3.8.0-3.9.0.sql
  31. 2 0
      htdocs/product/class/productcustomerprice.class.php
  32. 18 9
      htdocs/product/price.php
  33. 5 5
      htdocs/societe/price.php
  34. 15 14
      scripts/emailings/mailing-send.php

+ 6 - 4
build/makepack-dolibarr.pl

@@ -1150,14 +1150,16 @@ if ($nboftargetok) {
 	    		
 	    		if ($target eq 'SF') { 
 	    			$destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD;
-		    		print "Publish file ".$file." to $NEWPUBLISH/".$filestoscan{$file}."\n";
+		    		print "Publish file ".$file." to $NEWPUBLISH/".$filestoscan{$file}."/".$MAJOR.'.'.$MINOR.'.'.$BUILD."\n";
 	    		}
 	    		else
 	    		{
+	    			$dirnameonly=$file;
+	    			$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;  
 	    			$filenameonly=$file;
-	    			$filenameonly =~ s/.*\/([^\/]+\/[^\/]+)$/$1/;      # removes path  
-	    			$destFolder="$NEWPUBLISH/$filenameonly";
-		    		print "Publish file ".$file." to $NEWPUBLISH/".$filenameonly."\n";
+	    			$filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/;  
+	    			$destFolder="$NEWPUBLISH/$dirnameonly";
+		    		print "Publish file ".$file." to $NEWPUBLISH/".$dirnameonly."\n";
 	    		}
 
 				# mkdir	   

+ 1 - 0
htdocs/accountancy/journal/purchasesjournal.php

@@ -94,6 +94,7 @@ $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid =
 $sql .= " JOIN " . MAIN_DB_PREFIX . "facture_fourn as f ON f.rowid = fd.fk_facture_fourn";
 $sql .= " JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc";
 $sql .= " WHERE f.fk_statut > 0 ";
+$sql .= " AND fd.fk_code_ventilation > 0 ";
 if (! empty($conf->multicompany->enabled)) {
 	$sql .= " AND f.entity IN (" . getEntity("facture_fourn", 1) . ")";
 }

+ 1 - 1
htdocs/adherents/list.php

@@ -58,7 +58,7 @@ if ($page == -1) { $page = 0; }
 $offset = $limit * $page ;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
-if (! $sortorder) { $sortorder=($filter=='outofdate'?"ASC":"DESC"); }
+if (! $sortorder) { $sortorder=($filter=='outofdate'?"DESC":"ASC"); }
 if (! $sortfield) { $sortfield=($filter=='outofdate'?"d.datefin":"d.lastname"); }
 
 if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers

+ 22 - 9
htdocs/admin/confexped.php

@@ -2,8 +2,8 @@
 /* Copyright (C) 2004-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
- * Copyright (C) 2011-2015 Juanjo Menent		<jmenent@2byte.es>ù
- * Copyright (C) 2015			 Claudio Aschieri	<c.aschieri@19.coop>
+ * Copyright (C) 2011-2016 Juanjo Menent		<jmenent@2byte.es>ù
+ * Copyright (C) 2015      Claudio Aschieri     <c.aschieri@19.coop>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,21 +38,34 @@ if (!$user->admin)
 
 $action=GETPOST('action','alpha');
 
+
+/*
+ * Actions
+ */
+
 // Shipment note
+if (! empty($conf->expedition->enabled) && empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
+{
+    // This option should always be set to on when module is on.
+    dolibarr_set_const($db, "MAIN_SUBMODULE_EXPEDITION", "1",'chaine',0,'',$conf->entity);
+}
+/*
 if ($action == 'activate_sending')
 {
     dolibarr_set_const($db, "MAIN_SUBMODULE_EXPEDITION", "1",'chaine',0,'',$conf->entity);
     header("Location: confexped.php");
     exit;
 }
-else if ($action == 'disable_sending')
+if ($action == 'disable_sending')
 {
 	dolibarr_del_const($db, "MAIN_SUBMODULE_EXPEDITION",$conf->entity);
     header("Location: confexped.php");
     exit;
 }
+*/
+
 // Delivery note
-else if ($action == 'activate_delivery')
+if ($action == 'activate_delivery')
 {
     dolibarr_set_const($db, "MAIN_SUBMODULE_EXPEDITION", "1",'chaine',0,'',$conf->entity);    // We must also enable this
     dolibarr_set_const($db, "MAIN_SUBMODULE_LIVRAISON", "1",'chaine',0,'',$conf->entity);
@@ -68,8 +81,9 @@ else if ($action == 'disable_delivery')
 
 
 /*
- * Affiche page
+ * View
  */
+
 $dir = DOL_DOCUMENT_ROOT."/core/modules/expedition/";
 $form=new Form($db);
 
@@ -102,16 +116,15 @@ print '<td>'.$langs->trans("SendingsAbility").'</td>';
 print '<td align="center" width="20">';
 print '</td>';
 print '<td align="center" width="100">';
-
-if (empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
+print $langs->trans("Required");
+/*if (empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
 {
 	print '<a href="confexped.php?action=activate_sending">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
 }
 else
 {
 	print '<a href="confexped.php?action=disable_sending">'.img_picto($langs->trans("Enabled"),'switch_on').'</a>';
-}
-
+}*/
 print "</td>";
 print '</tr>';
 

+ 7 - 6
htdocs/admin/delais.php

@@ -1,8 +1,9 @@
 <?php
-/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2005      Simon Tosser         <simon@kornog-computing.com>
- * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
+ * Copyright (C) 2004-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
+ * Copyright (C) 2005       Simon Tosser            <simon@kornog-computing.com>
+ * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
+ * Copyright (C) 2016       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -164,7 +165,7 @@ if ($action == 'edit')
     		foreach($delays as $delay)
     		{
     			$var=!$var;
-    			$value=(! empty($conf->global->$delay['code'])?$conf->global->$delay['code']:0);
+				$value=(! empty($conf->global->{$delay['code']})?$conf->global->{$delay['code']}:0);
     			print '<tr '.$bc[$var].'>';
     			print '<td width="20px">'.img_object('',$delay['img']).'</td>';
     			print '<td>'.$langs->trans('Delays_'.$delay['code']).'</td><td>';
@@ -211,7 +212,7 @@ else
     		foreach($delays as $delay)
     		{
     			$var=!$var;
-    			$value=(! empty($conf->global->$delay['code'])?$conf->global->$delay['code']:0);
+				$value=(! empty($conf->global->{$delay['code']})?$conf->global->{$delay['code']}:0);
     			print '<tr '.$bc[$var].'>';
     			print '<td width="20px">'.img_object('',$delay['img']).'</td>';
     			print '<td>'.$langs->trans('Delays_'.$delay['code']).'</td>';

+ 48 - 47
htdocs/admin/dict.php

@@ -1,15 +1,16 @@
 <?php
-/* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2004      Benoit Mortier       <benoit.mortier@opensides.be>
- * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
- * Copyright (C) 2010-2013 Juanjo Menent        <jmenent@2byte.es>
- * Copyright (C) 2011-2015 Philippe Grand       <philippe.grand@atoo-net.com>
- * Copyright (C) 2011      Remy Younes          <ryounes@gmail.com>
- * Copyright (C) 2012-2015 Marcos García        <marcosgdf@gmail.com>
- * Copyright (C) 2012      Christophe Battarel	<christophe.battarel@ltairis.fr>
- * Copyright (C) 2011-2015 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
- * Copyright (C) 2015      Ferran Marcet        <fmarcet@2byte.es>
+/* Copyright (C) 2004       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
+ * Copyright (C) 2004-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
+ * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
+ * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
+ * Copyright (C) 2010-2013  Juanjo Menent           <jmenent@2byte.es>
+ * Copyright (C) 2011-2015  Philippe Grand          <philippe.grand@atoo-net.com>
+ * Copyright (C) 2011       Remy Younes             <ryounes@gmail.com>
+ * Copyright (C) 2012-2015  Marcos García           <marcosgdf@gmail.com>
+ * Copyright (C) 2012       Christophe Battarel     <christophe.battarel@ltairis.fr>
+ * Copyright (C) 2011-2015  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2015       Ferran Marcet           <fmarcet@2byte.es>
+ * Copyright (C) 2016       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1162,7 +1163,7 @@ if ($id)
                         {
                             $showfield=1;
                         	$align="left";
-                            $valuetoshow=$obj->$fieldlist[$field];
+                            $valuetoshow=$obj->{$fieldlist[$field]};
                             if ($value == 'type_template')
                             {
                                 $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow;
@@ -1199,77 +1200,77 @@ if ($id)
                             else if ($fieldlist[$field]=='libelle_facture') {
                                 $langs->load("bills");
                                 $key=$langs->trans("PaymentCondition".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "PaymentCondition".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "PaymentCondition".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                                 $valuetoshow=nl2br($valuetoshow);
                             }
                             else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_country') {
                                 $key=$langs->trans("Country".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "Country".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "Country".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_availability') {
                                 $langs->load("propal");
                                 $key=$langs->trans("AvailabilityType".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "AvailabilityType".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "AvailabilityType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_actioncomm') {
                                 $key=$langs->trans("Action".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "Action".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "Action".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if (! empty($obj->code_iso) && $fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_currencies') {
                                 $key=$langs->trans("Currency".strtoupper($obj->code_iso));
-                                $valuetoshow=($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_typent') {
                                 $key=$langs->trans(strtoupper($obj->code));
-                                $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_prospectlevel') {
                                 $key=$langs->trans(strtoupper($obj->code));
-                                $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_civility') {
                                 $key=$langs->trans("Civility".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') {
                             	$langs->load('agenda');
                                 $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_payment_term') {
                                 $langs->load("bills");
                                 $key=$langs->trans("PaymentConditionShort".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paiement') {
                                 $langs->load("bills");
                                 $key=$langs->trans("PaymentType".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "PaymentType".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "PaymentType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_reason') {
                                 $key=$langs->trans("DemandReasonType".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "DemandReasonType".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "DemandReasonType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_method') {
                                 $langs->load("orders");
                                 $key=$langs->trans($obj->code);
-                                $valuetoshow=($obj->code && $key != $obj->code)?$key:$obj->$fieldlist[$field];
+                                $valuetoshow=($obj->code && $key != $obj->code)?$key:$obj->{$fieldlist[$field]};
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_shipment_mode') {
                                 $langs->load("sendings");
                                 $key=$langs->trans("SendingMethod".strtoupper($obj->code));
-                                $valuetoshow=($obj->code && $key != "SendingMethod".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
+                                $valuetoshow=($obj->code && $key != "SendingMethod".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field] == 'libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paper_format')
                             {
                                 $key = $langs->trans('PaperFormat'.strtoupper($obj->code));
-                                $valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->$fieldlist[$field]);
+                                $valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_fees')
                             {
                                 $langs->load('trips');
                                 $key = $langs->trans(strtoupper($obj->code));
-                                $valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->$fieldlist[$field]);
+                                $valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') {
                                 $showfield=0;
@@ -1279,16 +1280,16 @@ if ($id)
                             }
                             else if ($fieldlist[$field]=='label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') {
 	                            $langs->load("products");
-	                            $valuetoshow=$langs->trans($obj->$fieldlist[$field]);
+	                            $valuetoshow=$langs->trans($obj->{$fieldlist[$field]});
                             }
                             else if ($fieldlist[$field]=='short_label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') {
 	                            $langs->load("products");
-	                            $valuetoshow = $langs->trans($obj->$fieldlist[$field]);
+	                            $valuetoshow = $langs->trans($obj->{$fieldlist[$field]});
                             }
                             else if (($fieldlist[$field] == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format'))
                             {
                             	$key = $langs->trans('SizeUnit'.strtolower($obj->unit));
-                                $valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->$fieldlist[$field]);
+                                $valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->{$fieldlist[$field]});
                             }
 
 							else if ($fieldlist[$field]=='localtax1_type') {
@@ -1504,7 +1505,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		{
 			if (! in_array('country',$fieldlist))	// If there is already a field country, we don't show country_id (avoid duplicate)
 			{
-				$country_id = (! empty($obj->$fieldlist[$field]) ? $obj->$fieldlist[$field] : 0);
+				$country_id = (! empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0);
 				print '<td>';
 				print '<input type="hidden" name="'.$fieldlist[$field].'" value="'.$country_id.'">';
 				print '</td>';
@@ -1518,7 +1519,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		}
 		elseif ($fieldlist[$field] == 'region_id')
 		{
-			$region_id = (! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:0);
+			$region_id = (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:0);
 			print '<td>';
 			print '<input type="hidden" name="'.$fieldlist[$field].'" value="'.$region_id.'">';
 			print '</td>';
@@ -1533,21 +1534,21 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		elseif ($fieldlist[$field] == 'type_template')
 		{
 			print '<td>';
-			print $form->selectarray('type_template', $elementList,(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''));
+			print $form->selectarray('type_template', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
 			print '</td>';
 		}
 		// Le type de l'element (pour les type de contact)
 		elseif ($fieldlist[$field] == 'element')
 		{
 			print '<td>';
-			print $form->selectarray('element', $elementList,(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''));
+			print $form->selectarray('element', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
 			print '</td>';
 		}
 		// La source de l'element (pour les type de contact)
 		elseif ($fieldlist[$field] == 'source')
 		{
 			print '<td>';
-			print $form->selectarray('source', $sourceList,(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''));
+			print $form->selectarray('source', $sourceList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
 			print '</td>';
 		}
 		elseif ($fieldlist[$field] == 'type' && $tabname == MAIN_DB_PREFIX."c_actioncomm")
@@ -1558,18 +1559,18 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		}
 		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible') {
 			print '<td>';
-			print $form->selectyesno($fieldlist[$field],(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''),1);
+			print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1);
 			print '</td>';
 		}
 		elseif (in_array($fieldlist[$field],array('nbjour','decalage','taux','localtax1','localtax2'))) {
 			$align="left";
 			if (in_array($fieldlist[$field],array('taux','localtax1','localtax2'))) $align="right";	// Fields aligned on right
 			print '<td align="'.$align.'">';
-			print '<input type="text" class="flat" value="'.(isset($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'" size="3" name="'.$fieldlist[$field].'">';
+			print '<input type="text" class="flat" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" size="3" name="'.$fieldlist[$field].'">';
 			print '</td>';
 		}
 		elseif (in_array($fieldlist[$field], array('libelle_facture'))) {
-			print '<td><textarea cols="30" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'</textarea></td>';
+			print '<td><textarea cols="30" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'</textarea></td>';
 		}
 		elseif (in_array($fieldlist[$field], array('content')))
 		{
@@ -1580,18 +1581,18 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			else print '<td>';
 			if ($context != 'hide')
 			{
-				//print '<textarea cols="3" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'</textarea>';
-				$doleditor = new DolEditor($fieldlist[$field], (! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''), '', 140, 'dolibarr_mailings', 'In', 0, false, true, ROWS_5, '90%');
+				//print '<textarea cols="3" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'</textarea>';
+				$doleditor = new DolEditor($fieldlist[$field], (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), '', 140, 'dolibarr_mailings', 'In', 0, false, true, ROWS_5, '90%');
 				print $doleditor->Create(1);
 			}
 			else print '&nbsp;';
 			print '</td>';
 		}
 		elseif ($fieldlist[$field] == 'price' || preg_match('/^amount/i',$fieldlist[$field])) {
-			print '<td><input type="text" class="flat" value="'.price((! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'')).'" size="8" name="'.$fieldlist[$field].'"></td>';
+			print '<td><input type="text" class="flat" value="'.price((! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')).'" size="8" name="'.$fieldlist[$field].'"></td>';
 		}
-		elseif ($fieldlist[$field] == 'code' && isset($obj->$fieldlist[$field])) {
-			print '<td><input type="text" class="flat" value="'.(! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'" size="10" name="'.$fieldlist[$field].'"></td>';
+		elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
+			print '<td><input type="text" class="flat" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" size="10" name="'.$fieldlist[$field].'"></td>';
 		}
 		elseif ($fieldlist[$field]=='unit') {
 			print '<td>';
@@ -1601,14 +1602,14 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 					'point' => $langs->trans('SizeUnitpoint'),
 					'inch' => $langs->trans('SizeUnitinch')
 			);
-			print $form->selectarray('unit', $units, (! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''), 0, 0, 0);
+			print $form->selectarray('unit', $units, (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 0, 0, 0);
 			print '</td>';
 		}
 		// Le type de taxe locale
 		elseif ($fieldlist[$field] == 'localtax1_type' || $fieldlist[$field] == 'localtax2_type')
 		{
 			print '<td align="center">';
-			print $form->selectarray($fieldlist[$field], $localtax_typeList, (! empty($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:''));
+			print $form->selectarray($fieldlist[$field], $localtax_typeList, (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
 			print '</td>';
 		}
 		elseif ($fieldlist[$field] == 'accountancy_code' || $fieldlist[$field] == 'accountancy_code_sell' || $fieldlist[$field] == 'accountancy_code_buy')
@@ -1634,7 +1635,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			if ($fieldlist[$field]=='libelle') $size='size="32" ';
 			if ($fieldlist[$field]=='tracking') $size='size="92" ';
 			if ($fieldlist[$field]=='sortorder') $size='size="2" ';
-			print '<input type="text" '.$size.' class="flat" value="'.(isset($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'" name="'.$fieldlist[$field].'">';
+			print '<input type="text" '.$size.' class="flat" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
 			print '</td>';
 		}
 	}

+ 5 - 4
htdocs/admin/oauth.php

@@ -1,5 +1,6 @@
 <?php
 /* Copyright (C) 2015       Frederic France     <frederic.france@free.fr>
+ * Copyright (C) 2016       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -43,7 +44,7 @@ if (!$user->admin)
 
 $action = GETPOST('action', 'alpha');
 
-// Supported OAUTH (a provider is supported when a file xxx_oauth2callback.php is available into htdocs/core/modules/oauth)
+// Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth)
 $supportedoauth2array=array('OAUTH_GOOGLE_NAME'=>'google');
 
 // API access parameters OAUTH
@@ -346,14 +347,14 @@ foreach ($list as $key)
     $var = !$var;
     print '<tr '.$bc[$var].' class="value">';
     print '<td><label for="'.$key[1].'">'.$langs->trans($key[1]).'</label></td>';
-    print '<td><input type="text" size="100" id="'.$key[1].'" name="'.$key[1].'" value="'.$conf->global->$key[1].'">';
+    print '<td><input type="text" size="100" id="'.$key[1].'" name="'.$key[1].'" value="'.$conf->global->{$key[1]}.'">';
     print '</td></tr>';
 
     // Api Secret
     $var = !$var;
     print '<tr '.$bc[$var].' class="value">';
     print '<td><label for="'.$key[2].'">'.$langs->trans($key[2]).'</label></td>';
-    print '<td><input type="password" size="100" id="'.$key[2].'" name="'.$key[2].'" value="'.$conf->global->$key[2].'">';
+    print '<td><input type="password" size="100" id="'.$key[2].'" name="'.$key[2].'" value="'.$conf->global->{$key[2]}.'">';
     print '</td></tr>';
 
 }
@@ -368,4 +369,4 @@ print '</form>';
 
 
 llxFooter();
-$db->close();
+$db->close();

+ 9 - 6
htdocs/comm/mailing/card.php

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2004		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
  * Copyright (C) 2005-2012	Laurent Destailleur		<eldy@uers.sourceforge.net>
- * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
+ * Copyright (C) 2005-2016	Regis Houssin			<regis.houssin@capnetworks.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -222,6 +222,8 @@ if (empty($reshook))
 	                    $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
 	                    $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
 	                    $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $signature = ((!empty($user->signature) && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:'');
+
 	                    // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions)
 						$substitutionarray=array(
 								'__ID__' => $obj->source_id,
@@ -234,6 +236,7 @@ if (empty($reshook))
 								'__OTHER3__' => $other3,
 								'__OTHER4__' => $other4,
 								'__OTHER5__' => $other5,
+								'__SIGNATURE__' => $signature,	// Signature is empty when ran from command line or taken from user in parameter)
 								'__CHECK_READ__' => '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>',
 								'__UNSUBSCRIBE__' => '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>'
 						);
@@ -1095,10 +1098,10 @@ else
 			}
 
 			print '</table>';
-			
+
 			dol_fiche_end();
-			
-			
+
+
 
 			print "\n";
 			print '<form name="edit_mailing" action="card.php" method="post" enctype="multipart/form-data">'."\n";
@@ -1110,7 +1113,7 @@ else
 			print load_fiche_titre($langs->trans("EMail"),'','');
 
 			dol_fiche_head();
-			
+
 			print '<table class="border" width="100%">';
 
 			// Subject
@@ -1177,7 +1180,7 @@ else
 			print '</table>';
 
 			dol_fiche_end();
-			
+
 			print '<div class="center">';
 			print '<input type="submit" class="button" value="'.$langs->trans("Save").'" name="save">';
 			print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';

+ 3 - 2
htdocs/comm/propal.php

@@ -288,7 +288,7 @@ if (empty($reshook))
 		{
 			$db->begin();
 
-			// Si on a selectionne une propal a copier, on realise la copie
+			// If we select proposal to clone during creation (when option PROPAL_CLONE_ON_CREATE_PAGE is on)
 			if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal'))
 			{
 				if ($object->fetch(GETPOST('copie_propal')) > 0) {
@@ -316,7 +316,8 @@ if (empty($reshook))
 					$object->fk_incoterms = GETPOST('incoterm_id', 'int');
 					$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
 
-					$id = $object->create_from($user);
+					// the create is done below and further more the existing create_from function is quite hilarating
+					//$id = $object->create_from($user);
 				} else {
 					setEventMessages($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), null, 'errors');
 				}

+ 1 - 0
htdocs/comm/propal/class/propal.class.php

@@ -1064,6 +1064,7 @@ class Propal extends CommonObject
      */
     function create_from($user)
     {
+    	// i love this function because $this->products is not used in create function...
         $this->products=$this->lines;
 
         return $this->create($user);

+ 4 - 2
htdocs/comm/remise.php

@@ -30,6 +30,8 @@ $langs->load("companies");
 $langs->load("orders");
 $langs->load("bills");
 
+$id=GETPOST("id",'int');
+
 $socid = GETPOST('id','int');
 // Security check
 if ($user->societe_id > 0)
@@ -53,8 +55,8 @@ if (GETPOST('cancel') && ! empty($backtopage))
 if (GETPOST("action") == 'setremise')
 {
 	$object = new Societe($db);
-	$object->fetch($_GET["id"]);
-	$result=$object->set_remise_client($_POST["remise"],$_POST["note"],$user);
+	$object->fetch($id);
+	$result=$object->set_remise_client(price2num(GETPOST("remise")),GETPOST("note"),$user);
 
 	if ($result > 0)
 	{

+ 9 - 6
htdocs/compta/facture.php

@@ -3509,7 +3509,9 @@ else if ($id > 0 || ! empty($ref))
 			print ' ';
 
 			print $prevsits[0]->situation_counter;
-			for ($i = 1; $i < count($prevsits); $i++) {
+			$cprevsits = count($prevsits);
+
+		  for ($i = 1; $i < $cprevsits; $i++) {
 				print ' + ';
 				print $prevsits[$i]->situation_counter;
 			}
@@ -3530,7 +3532,7 @@ else if ($id > 0 || ! empty($ref))
 			print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
 
 			// Previous situation(s) deduction(s)
-			for ($i = 0; $i < count($prevsits); $i++) {
+			for ($i = 0; $i < $cprevsits; $i++) {
 				print '<tr><td>';
 				print '<a href="' . $_SERVER['PHP_SELF'] . '?facid=' . $prevsits[$i]->id . '">';
 				print $langs->trans('SituationDeduction');
@@ -3843,6 +3845,7 @@ else if ($id > 0 || ! empty($ref))
 				}
 			}
 
+			// deprecated. Useless because now we can use templates
 			if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) 			// For backward compatibility
 			{
 				if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) {
@@ -3898,7 +3901,7 @@ else if ($id > 0 || ! empty($ref))
 
 			// Classify paid
 			if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))
-				|| ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $resteapayer == 0 && $user->rights->facture->paiement && empty($discount->id))
+				|| ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $user->rights->facture->paiement && empty($discount->id))
 			)
 			{
 				print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a></div>';
@@ -3928,10 +3931,10 @@ else if ($id > 0 || ! empty($ref))
 				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=clone&amp;object=invoice">' . $langs->trans("ToClone") . '</a></div>';
 			}
 
-			// Clone as predefined
+			// Clone as predefined / Create template
 			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $object->statut == 0 && $user->rights->facture->creer)
 			{
-				if (! $objectidnext)
+				if (! $objectidnext && count($object->lines) > 0)
 				{
 					print '<div class="inline-block divButAction"><a class="butAction" href="facture/fiche-rec.php?facid=' . $object->id . '&amp;action=create">' . $langs->trans("ChangeIntoRepeatableInvoice") . '</a></div>';
 				}
@@ -3946,7 +3949,7 @@ else if ($id > 0 || ! empty($ref))
 				}
 			}
 
-			//Create next situation invoice
+			// Create next situation invoice
 			if ($user->rights->facture->creer && ($object->type == 5) && ($object->statut == 1 || $object->statut == 2)) {
 				if ($object->is_last_in_cycle() && $object->situation_final != 1) {
 					print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=create&amp;type=5&amp;origin=facture&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '" >' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';

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

@@ -384,7 +384,7 @@ abstract class CommonObject
      */
     function errorsToString()
     {
-    	return $this->error.(is_array($this->errors)?(($this->error!=''?' ':'').join(',',$this->errors)):'');
+    	return $this->error.(is_array($this->errors)?(($this->error!=''?', ':'').join(', ',$this->errors)):'');
     }
 
     /**
@@ -3351,6 +3351,8 @@ abstract class CommonObject
 				$text.= ' - '.(! empty($line->label)?$line->label:$label);
 				$description.=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($line->description));	// Description is what to show on popup. We shown nothing if already into desc.
 			}
+			
+			$line->pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx/100)), 'MU');
 
 			// Output template part (modules that overwrite templates must declare this into descriptor)
 			// Use global variables + $dateSelector + $seller and $buyer
@@ -3374,7 +3376,7 @@ abstract class CommonObject
 			if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("Label").'"';
 			else $placeholder=' title="'.$langs->trans("Label").'"';
 
-			$pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx/100)), 'MU');
+			$line->pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx/100)), 'MU');
 
 			// Output template part (modules that overwrite templates must declare this into descriptor)
 			// Use global variables + $dateSelector + $seller and $buyer

+ 25 - 24
htdocs/core/class/extrafields.class.php

@@ -1,12 +1,13 @@
 <?php
-/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
- * Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
- * Copyright (C) 2004      Benoit Mortier	    <benoit.mortier@opensides.be>
- * Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
- * Copyright (C) 2013	   Florian Henry        <forian.henry@open-concept.pro>
- * Copyright (C) 2015	   Charles-Fr BENKE     <charles.fr@benke.fr>
+/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
+ * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
+ * Copyright (C) 2004       Sebastien Di Cintio     <sdicintio@ressource-toi.org>
+ * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
+ * Copyright (C) 2009-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
+ * Copyright (C) 2009-2012  Regis Houssin           <regis.houssin@capnetworks.com>
+ * Copyright (C) 2013       Florian Henry           <forian.henry@open-concept.pro>
+ * Copyright (C) 2015       Charles-Fr BENKE        <charles.fr@benke.fr>
+ * Copyright (C) 2016       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -878,7 +879,7 @@ class ExtraFields
 						}
 						else
 						{
-							$labeltoshow=$obj->$InfoFieldList[1];
+							$labeltoshow=$obj->{$InfoFieldList[1]};
 						}
 						$labeltoshow=dol_trunc($labeltoshow,45);
 
@@ -899,12 +900,12 @@ class ExtraFields
 						{
 							if(!$notrans)
 							{
-								$translabel=$langs->trans($obj->$InfoFieldList[1]);
-								if ($translabel!=$obj->$InfoFieldList[1]) {
+								$translabel=$langs->trans($obj->{$InfoFieldList[1]});
+								if ($translabel!=$obj->{$InfoFieldList[1]}) {
 									$labeltoshow=dol_trunc($translabel,18);
 								}
 								else {
-									$labeltoshow=dol_trunc($obj->$InfoFieldList[1],18);
+									$labeltoshow=dol_trunc($obj->{$InfoFieldList[1]},18);
 								}
 							}
 							if (empty($labeltoshow)) $labeltoshow='(not defined)';
@@ -1055,7 +1056,7 @@ class ExtraFields
 								$labeltoshow .= $obj->$field_toshow . ' ';
 							}
 						} else {
-							$labeltoshow = $obj->$InfoFieldList[1];
+							$labeltoshow = $obj->{$InfoFieldList[1]};
 						}
 						$labeltoshow = dol_trunc($labeltoshow, 45);
 
@@ -1076,11 +1077,11 @@ class ExtraFields
 							$out .= '/>' . $labeltoshow . '<br>';
 						} else {
 							if (! $notrans) {
-								$translabel = $langs->trans($obj->$InfoFieldList[1]);
-								if ($translabel != $obj->$InfoFieldList[1]) {
+								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
+								if ($translabel != $obj->{$InfoFieldList[1]}) {
 									$labeltoshow = dol_trunc($translabel, 18);
 								} else {
-									$labeltoshow = dol_trunc($obj->$InfoFieldList[1], 18);
+									$labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
 								}
 							}
 							if (empty($labeltoshow))
@@ -1274,13 +1275,13 @@ class ExtraFields
 				else
 				{
 					$translabel='';
-					if (!empty($obj->$InfoFieldList[1])) {
-						$translabel=$langs->trans($obj->$InfoFieldList[1]);
+					if (!empty($obj->{$InfoFieldList[1]})) {
+						$translabel=$langs->trans($obj->{$InfoFieldList[1]});
 					}
-					if ($translabel!=$obj->$InfoFieldList[1]) {
+					if ($translabel!=$obj->{$InfoFieldList[1]}) {
 						$value=dol_trunc($translabel,18);
 					}else {
-						$value=$obj->$InfoFieldList[1];
+						$value=$obj->{$InfoFieldList[1]};
 					}
 				}
 			}
@@ -1354,13 +1355,13 @@ class ExtraFields
 							}
 						} else {
 							$translabel = '';
-							if (! empty($obj->$InfoFieldList[1])) {
-								$translabel = $langs->trans($obj->$InfoFieldList[1]);
+							if (! empty($obj->{$InfoFieldList[1]})) {
+								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
 							}
-							if ($translabel != $obj->$InfoFieldList[1]) {
+							if ($translabel != $obj->{$InfoFieldList[1]}) {
 								$value .= dol_trunc($translabel, 18) . '<BR>';
 							} else {
-								$value .= $obj->$InfoFieldList[1] . '<BR>';
+								$value .= $obj->{$InfoFieldList[1]} . '<BR>';
 							}
 						}
 					}

+ 14 - 9
htdocs/core/class/html.form.class.php

@@ -503,7 +503,8 @@ class Form
     		$ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>';
     	}
     	$ret.='</select>';
-    	$ret.='<input type="submit" name="confirmmassaction" disabled="disabled" class="button hideobject massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
+    	// Warning: if you set submit button to disabled, post using Enter will no more work
+    	$ret.='<input type="submit" name="confirmmassaction" class="button hideobject massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
     	$ret.='</div>';
     	
     	$ret.='<!-- JS CODE TO ENABLE mass action select -->
@@ -515,7 +516,6 @@ class Form
 	  				/* console.log( index + ": " + $( this ).text() ); */
 	  				if ($(this).is(\':checked\')) atleastoneselected++;
 	  			});
-	  			console.log(atleastoneselected);
 	  			if (atleastoneselected)
 	  			{
 	  				jQuery(".massaction").show();
@@ -531,6 +531,7 @@ class Form
     		jQuery(".checkforselect").click(function() {
     			initCheckForSelect();
 	  		});
+    	    /* Warning: if you set submit button to disabled, post using Enter will no more work
 	  		jQuery(".massactionselect").change(function() {
 	  			console.log( $( this ).val() );
 	  			if ($(this).val() != \'0\')
@@ -542,6 +543,7 @@ class Form
 	  				jQuery(".massactionconfirmed").prop(\'disabled\', true);
 	  			}
 	  		});
+    	    */
     	});
 		</script>
     	';
@@ -893,7 +895,7 @@ class Form
      *	@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	int		$showempty		Add an empty field
+     *	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line)
      * 	@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')))
@@ -902,7 +904,7 @@ class Form
      *	@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.
      */
-    function select_company($selected='', $htmlname='socid', $filter='', $showempty=0, $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='')
     {
     	$out='';
 
@@ -948,7 +950,7 @@ class Form
      *	@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	int		$showempty		Add an empty field
+     *	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line)
      * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
      * 	@param	int		$forcecombo		Force to use combo box
      *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
@@ -959,7 +961,7 @@ class Form
      *	@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
      */
-    function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='')
+    function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='')
     {
         global $conf,$user,$langs;
 
@@ -1016,10 +1018,13 @@ class Form
             $out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'"'.$nodatarole.'>'."\n";
 
             $textifempty='';
-            // Do not use textempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
-            //$textifempty=' ';
+            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
             //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
-            if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) $textifempty.=$langs->trans("All");
+            if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) 
+            {
+                if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty); 
+                else $textifempty.=$langs->trans("All");
+            }
             if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n";
 
             $num = $this->db->num_rows($resql);

+ 11 - 5
htdocs/core/class/html.formcompany.class.php

@@ -564,16 +564,21 @@ class FormCompany
 				}
 			}
 
-			// Refresh contacts list on thirdparty list change
-			$htmloption='';
 
 			$events=array();
+			// Add an entry 'method' to say 'yes, we must execute url with param action = method';
+			// Add an entry 'url' to say which url to execute
+			// Add an entry htmlname to say which element we must change once url is called 
+			// Add entry params => array('cssid' => 'attr') to say to remov or add attribute attr if answer of url return  0 or >0 lines 
+			// To refresh contacts list on thirdparty list change
 			$events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
+			
 			if (count($events))	// If there is some ajax events to run once selection is done, we add code here to run events
 			{
 				print '<script type="text/javascript">
 				jQuery(document).ready(function() {
 					$("#search_'.$htmlname.'").change(function() {
+					    console.log("Call runJsCodeForEvent'.$htmlname.'");
 						var obj = '.json_encode($events).';
 						$.each(obj, function(key,values) {
 							if (values.method.length) {
@@ -583,7 +588,7 @@ class FormCompany
 						/* Clean contact */
 						$("div#s2id_contactid>a>span").html(\'\');
 					});
-
+								    
 					// Function used to execute events when search_htmlname change
 					function runJsCodeForEvent'.$htmlname.'(obj) {
 						var id = $("#'.$htmlname.'").val();
@@ -609,6 +614,7 @@ class FormCompany
 											}
 										}
 									});
+						            /* console.log("Change select#"+htmlname+" with content "+response.value) */
 									$("select#" + htmlname).html(response.value);
 								}
 							}
@@ -619,8 +625,8 @@ class FormCompany
 			}
 
 			print "\n".'<!-- Input text for third party with Ajax.Autocompleter (selectCompaniesForNewContact) -->'."\n";
-			print '<input type="text" size="30" id="search_'.$htmlname.'" name="search_'.$htmlname.'" value="'.$name.'" '.$htmloption.' />';
-			print ajax_autocompleter(($socid?$socid:-1),$htmlname,DOL_URL_ROOT.'/societe/ajaxcompanies.php','',$minLength);
+			print '<input type="text" size="30" id="search_'.$htmlname.'" name="search_'.$htmlname.'" value="'.$name.'" />';
+			print ajax_autocompleter(($socid?$socid:-1), $htmlname, DOL_URL_ROOT.'/societe/ajaxcompanies.php', '', $minLength, 0);
 			return $socid;
 		}
 		else

+ 23 - 9
htdocs/core/lib/ajax.lib.php

@@ -35,29 +35,40 @@
  *  @param	string	$urloption			More parameters on URL request
  *  @param	int		$minLength			Minimum number of chars to trigger that Ajax search
  *  @param	int		$autoselect			Automatic selection if just one value
- *  @param	array	$ajaxoptions		Multiple options array (Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done)
+ *  @param	array	$ajaxoptions		Multiple options array 
+ *                                          Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done
+ *                                          Ex: array('disabled'=>
+ *                                          Ex: array('show'=>
+ *                                          Ex: array('update_textarea'=>
  *	@return string              		Script
  */
 function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array())
 {
     if (empty($minLength)) $minLength=1;
 
+    // Input search_htmlname is original field
+    // Input htmlname is a second input field used when using ajax autocomplete.
 	$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" />';
 
-	$script.= '<script type="text/javascript">';
+	$script.= '<!-- Javascript code for autocomplete of field '.$htmlname.' -->'."\n";
+	$script.= '<script type="text/javascript">'."\n";
 	$script.= '$(document).ready(function() {
 					var autoselect = '.$autoselect.';
 					var options = '.json_encode($ajaxoptions).';
 
-					// Remove product id before select another product
-					// use keyup instead change to avoid loosing the product id
+					/* Remove product id before select another product use keyup instead of change to avoid loosing the product id. This is needed only for select of predefined product */
+					/* TODO Check if we can remove this */
 					$("input#search_'.$htmlname.'").keydown(function() {
 						$("#'.$htmlname.'").val("");
 					});
-					$("input#search_'.$htmlname.'").change(function() {
+						    
+					/* I disable this. A call to trigger is already done later into the select action of the autocomplete code 
+						$("input#search_'.$htmlname.'").change(function() {
+					    console.log("Call the change trigger on input '.$htmlname.' because of a change on search_'.$htmlname.' was triggered");
 						$("#'.$htmlname.'").trigger("change");
-					});
-					// Check when keyup
+					});*/
+
+					// Check options for secondary actions when keyup
 					$("input#search_'.$htmlname.'").keyup(function() {
 						    if ($(this).val().length == 0)
 						    {
@@ -123,8 +134,9 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
 						},
 						dataType: "json",
     					minLength: '.$minLength.',
-    					select: function( event, ui ) {		// Function ran when new value is selected into javascript combo
-    						$("#'.$htmlname.'").val(ui.item.id).trigger("change");	// Select new value
+    					select: function( event, ui ) {		// Function ran once new value has been selected into javascript combo
+    						console.log("Call change on input '.$htmlname.' because of select definition of autocomplete select call on input#search_'.$htmlname.'");
+    					    $("#'.$htmlname.'").val(ui.item.id).trigger("change");	// Select new value
     						// Disable an element
     						if (options.option_disabled) {
     							if (ui.item.disabled) {
@@ -167,6 +179,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
 									}
     							});
     						}
+    						console.log("ajax_autocompleter new value selected, we trigger change on original component");
+    						$("#search_'.$htmlname.'").trigger("change");	// We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code.
     					}
     					,delay: 500
 					}).data("ui-autocomplete")._renderItem = function( ul, item ) {

+ 11 - 10
htdocs/core/lib/files.lib.php

@@ -1,8 +1,9 @@
 <?php
-/* Copyright (C) 2008-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
- * Copyright (C) 2012-2015	Regis Houssin		<regis.houssin@capnetworks.com>
- * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
- * Copyright (C) 2015		Marcos García		<marcosgdf@gmail.com>
+/* Copyright (C) 2008-2012  Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2012-2015  Regis Houssin       <regis.houssin@capnetworks.com>
+ * Copyright (C) 2012       Juanjo Menent       <jmenent@2byte.es>
+ * Copyright (C) 2015       Marcos García       <marcosgdf@gmail.com>
+ * Copyright (C) 2016       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -2273,18 +2274,18 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 		// Define $accessallowed
 		if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg))
 		{
-			if ($fuser->rights->$reg[1]->lire || $fuser->rights->$reg[1]->read || ($fuser->rights->$reg[1]->download)) $accessallowed=1;
-			$original_file=$conf->$reg[1]->dir_temp.'/'.$fuser->id.'/'.$original_file;
+			if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1;
+			$original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file;
 		}
 		else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg))
 		{
-			if ($fuser->rights->$reg[1]->lire || $fuser->rights->$reg[1]->read || ($fuser->rights->$reg[1]->download)) $accessallowed=1;
-			$original_file=$conf->$reg[1]->dir_temp.'/'.$original_file;
+			if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1;
+			$original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file;
 		}
 		else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg))
 		{
-			if ($fuser->rights->$reg[1]->lire || $fuser->rights->$reg[1]->read || ($fuser->rights->$reg[1]->download)) $accessallowed=1;
-			$original_file=$conf->$reg[1]->dir_output.'/'.$fuser->id.'/'.$original_file;
+			if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1;
+			$original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file;
 		}
 		else
 		{

+ 4 - 3
htdocs/core/lib/functions.lib.php

@@ -2037,11 +2037,12 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo
 {
 	global $conf;
 
-	if (empty($stringencoding)) $stringencoding='UTF-8';
-
 	if ($size==0 || ! empty($conf->global->MAIN_DISABLE_TRUNC)) return $string;
+	
+	if (empty($stringencoding)) $stringencoding='UTF-8';
 	// reduce for small screen
-    if ($conf->dol_optimize_smallscreen==1 && $display==1) $size = round($size/3);
+	if ($conf->dol_optimize_smallscreen==1 && $display==1) $size = round($size/3);
+
 	// We go always here
 	if ($trunc == 'right')
 	{

+ 2 - 2
htdocs/core/lib/functions2.lib.php

@@ -4,7 +4,7 @@
  * Copyright (C) 2008       Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
  * Copyright (C) 2014       Marcos García               <marcosgdf@gmail.com>
  * Copyright (C) 2015       Ferran Marcet               <fmarcet@2byte.es>
- * Copyright (C) 2015       Raphaël Doursenaud          <rdoursenaud@gpcsolutions.fr>
+ * Copyright (C) 2015-2016  Raphaël Doursenaud          <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1910,7 +1910,7 @@ function fetchObjectByElement($element_id, $element_type)
 	global $db,$conf;
 
     $element_prop = getElementProperties($element_type);
-    if (is_array($element_prop) && $conf->$element_prop['module']->enabled)
+    if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled)
     {
         dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php');
 

+ 10 - 2
htdocs/core/modules/modExpedition.class.php

@@ -83,7 +83,7 @@ class modExpedition extends DolibarrModules
 		// Constants
 		$this->const = array();
 		$r=0;
-
+		
 		$this->const[$r][0] = "EXPEDITION_ADDON_PDF";
 		$this->const[$r][1] = "chaine";
 		$this->const[$r][2] = "rouget";
@@ -124,7 +124,15 @@ class modExpedition extends DolibarrModules
 		$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/delivery";
 		$this->const[$r][3] = "";
 		$this->const[$r][4] = 0;
-
+		$r++;
+		
+		$this->const[$r][0] = "MAIN_SUBMODULE_EXPEDITION";
+		$this->const[$r][1] = "chaine";
+		$this->const[$r][2] = "1";
+		$this->const[$r][3] = "Enable shipments";
+		$this->const[$r][4] = 0;
+		$r++;
+		
 		// Boxes
 		$this->boxes = array();
 

+ 2 - 2
htdocs/core/modules/modOauth.class.php

@@ -139,8 +139,8 @@ class modOauth extends DolibarrModules
         $this->remove($options);
 
         $sql = array(
-            "CREATE TABLE IF NOT EXISTS llx_oauth_state (rowid int(11) NOT NULL AUTO_INCREMENT, service varchar(36), state varchar(128), fk_user int(11), fk_adherent int(11), entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
-            "CREATE TABLE IF NOT EXISTS llx_oauth_token (rowid int(11) NOT NULL AUTO_INCREMENT, service varchar(36), token text, fk_user int(11), fk_adherent int(11), entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
+            "CREATE TABLE IF NOT EXISTS ".MAIN_DB_PREFIX."oauth_state (rowid int(11) NOT NULL AUTO_INCREMENT, service varchar(36), state varchar(128), fk_user int(11), fk_adherent int(11), entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
+            "CREATE TABLE IF NOT EXISTS ".MAIN_DB_PREFIX."oauth_token (rowid int(11) NOT NULL AUTO_INCREMENT, service varchar(36), token text, fk_user int(11), fk_adherent int(11), entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
             );
 
         return $this->_init($sql,$options);

+ 5 - 1
htdocs/core/modules/modSociete.class.php

@@ -286,7 +286,11 @@ class modSociete extends DolibarrModules
         			case 'sellist':
 						$tmp='';
 						$tmpparam=unserialize($obj->param);	// $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
-						if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options']));
+						if ($tmpparam['options'] && is_array($tmpparam['options'])) 
+        				{
+							$stack=array_keys($tmpparam['options']);
+							$tmp=array_shift($stack);
+						}
 						if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
 						break;
         		}

+ 1 - 1
htdocs/core/modules/oauth/google_oauthcallback.php

@@ -45,7 +45,7 @@ $backtourl = GETPOST('backtourl', 'alpha');
 $uriFactory = new \OAuth\Common\Http\Uri\UriFactory();
 //$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
 //$currentUri->setQuery('');
-$currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php');
+$currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/google_oauthcallback.php');
 
 
 /**

+ 8 - 8
htdocs/core/modules/printing/printgcp.modules.php

@@ -75,7 +75,7 @@ class printing_printgcp extends PrintingDriver
         $credentials = new Credentials(
             $this->google_id,
             $this->google_secret,
-            $urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php'
+            $urlwithroot.'/core/modules/oauth/google_oauthcallback.php'
         );
         $access = ($storage->hasAccessToken('Google')?'HasAccessToken':'NoAccessToken');
         $serviceFactory = new \OAuth\ServiceFactory();
@@ -113,7 +113,7 @@ class printing_printgcp extends PrintingDriver
          
             if ($this->google_id != '' && $this->google_secret != '') {
                 $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthConfigured', 'type'=>'info');
-                $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_ACCESS', 'info'=>$access, 'type'=>'info', 'renew'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?state=userinfo_email,userinfo_profile,cloud_print&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'delete'=>($storage->hasAccessToken('Google')?$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'):''));
+                $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_ACCESS', 'info'=>$access, 'type'=>'info', 'renew'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?state=userinfo_email,userinfo_profile,cloud_print&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'delete'=>($storage->hasAccessToken('Google')?$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'):''));
                 if ($token_ok) {
                     $refreshtoken = $token->getRefreshToken();
                     $this->conf[] = array('varname'=>'PRINTGCP_TOKEN_REFRESH',   'info'=>((! empty($refreshtoken))?'Yes':'No'), 'type'=>'info');
@@ -122,10 +122,10 @@ class printing_printgcp extends PrintingDriver
                 }
                 /*
                 if ($storage->hasAccessToken('Google')) {
-                    $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
-                    $this->conf[] = array('varname'=>'PRINTGCP_DELETE_TOKEN', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'delete');
+                    $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
+                    $this->conf[] = array('varname'=>'PRINTGCP_DELETE_TOKEN', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'delete');
                 } else {
-                    $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/getgoogleoauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
+                    $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
                 }*/
             } else {
                 $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthNotConfigured', 'type'=>'info');
@@ -200,7 +200,7 @@ class printing_printgcp extends PrintingDriver
         $credentials = new Credentials(
             $this->google_id,
             $this->google_secret,
-            DOL_MAIN_URL_ROOT.'/core/modules/oauth/getgoogleoauthcallback.php'
+            DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
         );
         $serviceFactory = new \OAuth\ServiceFactory();
         $apiService = $serviceFactory->createService('Google', $credentials, $storage, array());
@@ -338,7 +338,7 @@ class printing_printgcp extends PrintingDriver
         $credentials = new Credentials(
             $this->google_id,
             $this->google_secret,
-            DOL_MAIN_URL_ROOT.'/core/modules/oauth/getoauthcallback.php?service=google'
+            DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php?service=google'
         );
         $serviceFactory = new \OAuth\ServiceFactory();
         $apiService = $serviceFactory->createService('Google', $credentials, $storage, array());
@@ -387,7 +387,7 @@ class printing_printgcp extends PrintingDriver
         $credentials = new Credentials(
             $this->google_id,
             $this->google_secret,
-            DOL_MAIN_URL_ROOT.'/core/modules/oauth/getgoogleoauthcallback.php'
+            DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
         );
         $serviceFactory = new \OAuth\ServiceFactory();
         $apiService = $serviceFactory->createService('Google', $credentials, $storage, array());

+ 18 - 14
htdocs/expedition/card.php

@@ -9,6 +9,7 @@
  * Copyright (C) 2014		Cedric GROSS			<c.gross@kreiz-it.fr>
  * Copyright (C) 2014-2015	Francis Appels			<francis.appels@yahoo.com>
  * Copyright (C) 2015		Claudio Aschieri		<c.aschieri@19.coop>
+ * Copyright (C) 2016		Ferran Marcet			<fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -242,7 +243,7 @@ if (empty($reshook))
 			}
 			else
 			{
-			    var_dump($_POST); var_dump($batch);
+			    //var_dump($_POST); var_dump($batch);
 				//shipment line for product with no batch management and no multiple stock location
 				if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
 			}
@@ -278,7 +279,7 @@ if (empty($reshook))
     					{
     					    if ($stockLine[$i][$j]['qty']>0)
     					    {
-    					        $ret=$object->addline($stockLine[$i][$j]['warehouse_id'], $stockLine[$i][$j]['ix_l'], $stockLine[$i][$j]['qty']);
+    					        $ret=$object->addline($stockLine[$i][$j]['warehouse_id'], $stockLine[$i][$j]['ix_l'], $stockLine[$i][$j]['qty'], $array_options[$i]);
     					        if ($ret < 0)
     					        {
     					            setEventMessages($object->error, $object->errors, 'errors');
@@ -287,19 +288,22 @@ if (empty($reshook))
     					    }
     					}
 					}
-					if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
+					else
 					{
-						$ent = "entl".$i;
-						$idl = "idl".$i;
-						$entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int');
-						if ($entrepot_id < 0) $entrepot_id='';
-						if (! ($objectsrc->lines[$i]->fk_product > 0)) $entrepot_id = 0;
-						
-						$ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int'),$array_options[$i]);
-						if ($ret < 0)
+						if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
 						{
-							setEventMessages($object->error, $object->errors, 'errors');
-							$error++;
+							$ent = "entl".$i;
+							$idl = "idl".$i;
+							$entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int');
+							if ($entrepot_id < 0) $entrepot_id='';
+							if (! ($objectsrc->lines[$i]->fk_product > 0)) $entrepot_id = 0;
+						
+							$ret=$object->addline($entrepot_id, GETPOST($idl,'int'), GETPOST($qty,'int'), $array_options[$i]);
+							if ($ret < 0)
+							{
+								setEventMessages($object->error, $object->errors, 'errors');
+								$error++;
+							}
 						}
 					}
 				}
@@ -790,7 +794,7 @@ if ($action == 'create')
                 print "<tr ".$bc[$var].">\n";
                 
                 // Product label
-                if ($line->fk_product > 0)  // Predefined product ?
+                if ($line->fk_product > 0)  // If predefined product
                 {
                     $product->fetch($line->fk_product);
                     $product->load_stock();

+ 29 - 7
htdocs/expedition/class/expedition.class.php

@@ -8,7 +8,8 @@
  * Copyright (C) 2014		Cedric GROSS			<c.gross@kreiz-it.fr>
  * Copyright (C) 2014-2015  Marcos García           <marcosgdf@gmail.com>
  * Copyright (C) 2014-2015  Francis Appels          <francis.appels@yahoo.com>
- * Copyright (C) 2015				Claudio Aschieri				<c.aschieri@19.coop>
+ * Copyright (C) 2015       Claudio Aschieri        <c.aschieri@19.coop>
+ * Copyright (C) 2016		Ferran Marcet			<fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -870,13 +871,23 @@ class Expedition extends CommonObject
 				return -1;
 			}
 
-			if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)	// FIXME Check is done for stock of product, it must be done for stock of product into warehouse if $entrepot_id defined
+			if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)
 			{
+			    // Check must be done for stock of product into warehouse if $entrepot_id defined
 				$product=new Product($this->db);
 				$result=$product->fetch($fk_product);
-				$product_type=$product->type;
 
-				if ($product_type == 0 && $product->stock_reel < $qty)
+				$product_type=$product->type;
+				if ($entrepot_id > 0) {
+                    $product->load_stock();
+				    $product_stock = $product->stock_warehouse[$entrepot_id]->real;
+				}
+				else 
+				{
+				    $product_stock = $product->stock_reel;
+				}
+				
+				if ($product_type == 0 && $product_stock < $qty)
 				{
 					$this->error=$langs->trans('ErrorStockIsNotEnough');
 					$this->db->rollback();
@@ -901,8 +912,8 @@ class Expedition extends CommonObject
 	 */
 	function addline_batch($dbatch,$array_options=0)
 	{
-		global $conf;
-		
+		global $conf,$langs;
+
 		$num = count($this->lines);
 		if ($dbatch['qty']>0)
 		{
@@ -928,7 +939,17 @@ class Expedition extends CommonObject
 
 					if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)
 					{
-						// TODO
+						require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
+						$prod_batch = new Productbatch($this->db);
+						$prod_batch->fetch($value['id_batch']);
+
+						if ($prod_batch->qty < $linebatch->dluo_qty)
+						{
+							$this->errors[] = $langs->trans('ErrorStockIsNotEnough');
+							dol_syslog(get_class($this)."::addline_batch error=Product ".$prod_batch->batch.": ".$this->errorsToString(), LOG_ERR);
+							$this->db->rollback();
+							return -1;
+						}
 					}
 					
 					//var_dump($linebatch);
@@ -945,6 +966,7 @@ class Expedition extends CommonObject
 			
 			//var_dump($line);
 			$this->lines[$num] = $line;
+			return 1;
 		}
 	}
 

+ 6 - 5
htdocs/exports/class/export.class.php

@@ -1,7 +1,8 @@
 <?php
-/* Copyright (C) 2005-2011	Laurent Destailleur	<eldy@users.sourceforge.net>
- * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
- * Copyright (C) 2012		Charles-Fr BENKE	<charles.fr@benke.fr>
+/* Copyright (C) 2005-2011  Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2005-2012  Regis Houssin       <regis.houssin@capnetworks.com>
+ * Copyright (C) 2012       Charles-Fr BENKE    <charles.fr@benke.fr>
+ * Copyright (C) 2016       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -131,11 +132,11 @@ class Export
     									//print_r("$perm[0]-$perm[1]-$perm[2]<br>");
     									if (! empty($perm[2]))
     									{
-    										$bool=$user->rights->$perm[0]->$perm[1]->$perm[2];
+    										$bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]};
     									}
     									else
     									{
-    										$bool=$user->rights->$perm[0]->$perm[1];
+    										$bool=$user->rights->{$perm[0]}->{$perm[1]};
     									}
     									if ($perm[0]=='user' && $user->admin) $bool=true;
     									if (! $bool) break;

+ 4 - 3
htdocs/imports/class/import.class.php

@@ -1,5 +1,6 @@
 <?php
-/* Copyright (C) 2011 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2011       Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2016       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -106,11 +107,11 @@ class Import
 						//print_r("$perm[0]-$perm[1]-$perm[2]<br>");
 						if ($perm[2])
 						{
-						$bool=$user->rights->$perm[0]->$perm[1]->$perm[2];
+						$bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]};
 						}
 						else
 						{
-						$bool=$user->rights->$perm[0]->$perm[1];
+						$bool=$user->rights->{$perm[0]}->{$perm[1]};
 						}
 						if ($perm[0]=='user' && $user->admin) $bool=true;
 						//print $bool." $perm[0]"."<br>";

+ 3 - 3
htdocs/install/mysql/migration/3.8.0-3.9.0.sql

@@ -34,9 +34,6 @@ ALTER TABLE llx_actioncomm ADD COLUMN email_tocc varchar(256) after email_to;
 ALTER TABLE llx_actioncomm ADD COLUMN email_tobcc varchar(256) after email_tocc;
 
 
-UPDATE llx_commande_fourn set billed=1 where statut = 8;
-UPDATE llx_commande_fourn set statut=5 where statut = 8 and billed=1;
-
 ALTER TABLE llx_user MODIFY COLUMN pass varchar(128);
 ALTER TABLE llx_user MODIFY COLUMN pass_temp varchar(128); 
 
@@ -111,6 +108,9 @@ ALTER TABLE llx_commande ADD COLUMN fk_warehouse integer DEFAULT NULL AFTER fk_s
 ALTER TABLE llx_commande_fournisseur ADD COLUMN billed smallint DEFAULT 0 AFTER fk_statut;
 ALTER TABLE llx_commande_fournisseur ADD INDEX billed (billed);
 
+UPDATE llx_commande_fournisseur set billed=1 where statut = 8;
+UPDATE llx_commande_fournisseur set statut=5 where statut = 8 and billed=1;
+
 ALTER TABLE llx_product ADD COLUMN cost_price	double(24,8) DEFAULT NULL;
 
 ALTER TABLE llx_ecm_directories MODIFY COLUMN fullpath varchar(750);

+ 2 - 0
htdocs/product/class/productcustomerprice.class.php

@@ -341,6 +341,8 @@ class Productcustomerprice extends CommonObject
 					$sql .= ' AND ' . $key . ' = \'' . $value . '\'';
 				} elseif ($key == 'soc.nom') {
 					$sql .= ' AND ' . $key . ' LIKE \'%' . $value . '%\'';
+				} elseif ($key == 'prod.ref') {
+					$sql .= ' AND ' . $key . ' LIKE \'%' . $value . '%\'';
 				} else {
 					$sql .= ' AND ' . $key . ' = ' . $value;
 				}

+ 18 - 9
htdocs/product/price.php

@@ -44,6 +44,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
 
 $langs->load("products");
 $langs->load("bills");
+$langs->load("companies");
 
 $mesg=''; $error=0; $errors=array();
 
@@ -346,8 +347,16 @@ if (empty($reshook))
 		$prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx"));
 		$prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0);
 
+		if (! ($prodcustprice->fk_soc > 0))
+		{
+		    $langs->load("errors");
+		    setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ThirdParty")), null, 'errors');
+		    $error++;
+		    $action='add_customer_price';
+		}
 		if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $prodcustprice->price_min<$maxpricesupplier)
 		{
+		    $langs->load("errors");
 			setEventMessages($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')), null, 'errors');
 			$error++;
 			$action='add_customer_price';
@@ -548,7 +557,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES))
 				print '<tr><td>' . $langs->trans("PriceByQuantity") . ' ' . $i;
 				print '</td><td>';
 
-				if ($object->prices_by_qty [$i] == 1) {
+				if ($object->prices_by_qty[$i] == 1) {
 					print '<table width="50%" class="border" summary="List of quantities">';
 
 					print '<tr class="liste_titre">';
@@ -558,7 +567,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES))
 					print '<td align="right">' . $langs->trans("Discount") . '</td>';
 					print '<td>&nbsp;</td>';
 					print '</tr>';
-					foreach ($object->prices_by_qty_list [$i] as $ii => $prices) {
+					foreach ($object->prices_by_qty_list[$i] as $ii => $prices) {
 						if ($action == 'edit_price_by_qty' && $rowid == $prices['rowid'] && ($user->rights->produit->creer || $user->rights->service->creer)) {
 							print '<form action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="POST">';
 							print '<input type="hidden" name="action" value="update_price_by_qty">';
@@ -574,7 +583,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES))
 							print '</form>';
 						} else {
 							print '<tr class="' . ($ii % 2 == 0 ? 'pair' : 'impair') . '">';
-							print '<td>' . $prices ['quantity'] . '</td>';
+							print '<td>' . $prices['quantity'] . '</td>';
 							print '<td align="right">' . price($prices['price']) . '</td>';
 							print '<td align="right">' . price($prices['unitprice']) . '</td>';
 							print '<td align="right">' . price($prices['remise_percent']) . ' %</td>';
@@ -1177,7 +1186,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
 
 	if ($action == 'add_customer_price')
 	{
-		// Create mode
+		// Form to add a new customer price
 		$maxpricesupplier = $object->min_recommended_price();
 
 		print load_fiche_titre($langs->trans('PriceByCustomer'));
@@ -1188,19 +1197,19 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
 		print '<input type="hidden" name="id" value="' . $object->id . '">';
 		print '<table class="border" width="100%">';
 		print '<tr>';
-		print '<td>' . $langs->trans('ThirdParty') . '</td>';
+		print '<td class="fieldrequired">' . $langs->trans('ThirdParty') . '</td>';
 		print '<td>';
-		print $form->select_company('', 'socid', 's.client in (1,2,3) AND s.rowid NOT IN (SELECT fk_soc FROM ' . MAIN_DB_PREFIX . 'product_customer_price WHERE fk_product='.$object->id.')', 1, 0, 0, array(), 0, 'minwidth300');
+		print $form->select_company('', 'socid', 's.client in (1,2,3) AND s.rowid NOT IN (SELECT fk_soc FROM ' . MAIN_DB_PREFIX . 'product_customer_price WHERE fk_product='.$object->id.')', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
 		print '</td>';
 		print '</tr>';
 
 		// VAT
-		print '<tr><td>' . $langs->trans("VATRate") . '</td><td>';
+		print '<tr><td class="fieldrequired">' . $langs->trans("VATRate") . '</td><td>';
 		print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr);
 		print '</td></tr>';
 
 		// Price base
-		print '<tr><td width="15%">';
+		print '<tr><td class="fieldrequired">';
 		print $langs->trans('PriceBase');
 		print '</td>';
 		print '<td>';
@@ -1209,7 +1218,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
 		print '</tr>';
 
 		// Price
-		print '<tr><td width="20%">';
+		print '<tr><td class="fieldrequired">';
 		$text = $langs->trans('SellingPrice');
 		print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
 		print '</td><td>';

+ 5 - 5
htdocs/societe/price.php

@@ -212,9 +212,9 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
 		't.fk_soc' => $object->id
 	);
 
-	$search_soc = GETPOST('search_soc');
-	if (! empty($search_soc)) {
-		$filter['soc.nom'] = $search_soc;
+	$search_prod = GETPOST('search_prod');
+	if (! empty($search_prod)) {
+		$filter ['prod.ref'] = $search_prod;
 	}
 
 	if ($action == 'add_customer_price') {
@@ -479,7 +479,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
             setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
         }
         
-        $option = '&search_soc=' . $search_soc . '&id=' . $object->id;
+        $option = '&search_prod=' . $search_prod . '&id=' . $object->id;
         
         print_barre_liste($langs->trans('PriceForEachProduct'), $page, $_SERVEUR['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords, '');
         
@@ -505,7 +505,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
         {
             
             print '<tr class="liste_titre">';
-            print '<td><input type="text" class="flat" name="search_soc" value="' . $search_soc . '" size="20"></td>';
+			print '<td><input type="text" class="flat" name="search_prod" value="' . $search_prod . '" size="20"></td>';
             print '<td colspan="8">&nbsp;</td>';
             // Print the search button
             print '<td class="liste_titre" align="right">';

+ 15 - 14
scripts/emailings/mailing-send.php

@@ -1,8 +1,9 @@
 #!/usr/bin/env php
 <?php
 /*
- * Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2005-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
+ * Copyright (C) 2005-2013	Laurent Destailleur		<eldy@users.sourceforge.net>
+ * Copyright (C) 2005-2016	Regis Houssin			<regis.houssin@capnetworks.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -68,7 +69,7 @@ if (! empty($login)) $user->fetch('',$login);
 $sql = "SELECT m.rowid, m.titre, m.sujet, m.body,";
 $sql.= " m.email_from, m.email_replyto, m.email_errorsto";
 $sql.= " FROM ".MAIN_DB_PREFIX."mailing as m";
-$sql.= " WHERE m.statut = 1";
+$sql.= " WHERE m.statut IN (1,2)";
 if ($id != 'all')
 {
 	$sql.= " AND m.rowid= ".$id;
@@ -142,17 +143,17 @@ if ($resql)
 
 						// Make subtsitutions on topic and body
 						$other=explode(';',$obj2->other);
-						$other1=$other[0];
-						$other2=$other[1];
-						$other3=$other[2];
-						$other4=$other[3];
-						$other5=$other[4];
-						// Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions)
-						$signature = (!empty($user->signature))?$user->signature:''; 
-						
+						$tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $signature = ((!empty($user->signature) && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:'');
+
+						// Array of possible substitutions (See also file mailing-send.php that should manage same substitutions)
 						$substitutionarray=array(
-							'__ID__' => $obj->source_id,
-							'__EMAIL__' => $obj->email,
+							'__ID__' => $obj2->source_id,
+							'__EMAIL__' => $obj2->email,
 							'__LASTNAME__' => $obj2->lastname,
 							'__FIRSTNAME__' => $obj2->firstname,
 							'__MAILTOEMAIL__' => '<a href="mailto:'.$obj2->email.'">'.$obj2->email.'</a>',
@@ -251,7 +252,7 @@ if ($resql)
 										$error++;
 									}
 								}
-                                
+
                                 if (!empty($conf->global->MAILING_DELAY)) {
                                     sleep($conf->global->MAILING_DELAY);
                                 }