From 017b18d5c6d5941ad49443bfa8b25dc99fbf21b8 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Sun, 27 Nov 2016 15:53:47 +0100
Subject: [PATCH] Fix #6037 #6041

---
 htdocs/commande/class/commande.class.php      | 104 ++++++++++--------
 htdocs/compta/facture/class/facture.class.php |  72 ++++++------
 htdocs/contrat/class/contrat.class.php        | 102 +++++++++--------
 htdocs/langs/en_US/bills.lang                 |   2 +-
 4 files changed, 156 insertions(+), 124 deletions(-)

diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 177e58caef9..10ca4018ff5 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -875,54 +875,70 @@ class Commande extends CommonOrder
                     	$this->ref = $initialref;
 
                         // Add object linked
-                        if (is_array($this->linked_objects) && ! empty($this->linked_objects))
+                        if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
                         {
-                        	foreach($this->linked_objects as $origin => $origin_id)
+                        	foreach($this->linked_objects as $origin => $tmp_origin_id)
                         	{
-                        		$ret = $this->add_object_linked($origin, $origin_id);
-                        		if (! $ret)
-                        		{
-                        			dol_print_error($this->db);
-                        			$error++;
-                        		}
-
-                        		if (! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN))
-                        		{
-                        		    $originforcontact = $origin;
-                        		    $originidforcontact = $origin_id;
-                        		    if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
-                        		    {
-                        		        require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
-                        		        $exp = new Expedition($db);
-                        		        $exp->fetch($origin_id);
-                        		        $exp->fetchObjectLinked();
-                        		        if (count($exp->linkedObjectsIds['commande']) > 0)
-                        		        {
-                        		            foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
-                        		            {
-                        		                $originforcontact = 'commande';
-                        		                $originidforcontact = $value->id;
-                        		                break; // We take first one
-                        		            }
-                        		        }
-                        		    }
-
-                        		    $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
-                        		    $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
-
-                        		    $resqlcontact = $this->db->query($sqlcontact);
-                        		    if ($resqlcontact)
-                        		    {
-                        		        while($objcontact = $this->db->fetch_object($resqlcontact))
-                        		        {
-                					        //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
-                        		            $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
-                        		        }
-                        		    }
-                        		    else dol_print_error($resqlcontact);
-                        		}
+                        	    if (is_array($tmp_origin_id))       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
+                        	    {
+                        	        foreach($tmp_origin_id as $origin_id)
+                        	        {
+                        	            $ret = $this->add_object_linked($origin, $origin_id);
+                        	            if (! $ret)
+                        	            {
+                        	                dol_print_error($this->db);
+                        	                $error++;
+                        	            }
+                        	        }
+                        	    }
+                        	    else                                // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
+                        	    {
+                        	        $origin_id = $tmp_origin_id;
+                        	        $ret = $this->add_object_linked($origin, $origin_id);
+                        	        if (! $ret)
+                        	        {
+                        	            dol_print_error($this->db);
+                        	            $error++;
+                        	        }
+                          	    }
                         	}
                         }
+
+            			if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id))   // Get contact from origin object
+            			{
+            				$originforcontact = $this->origin;
+            				$originidforcontact = $this->origin_id;
+                		    if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
+                		    {
+                		        require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
+                		        $exp = new Expedition($db);
+                		        $exp->fetch($this->origin_id);
+                		        $exp->fetchObjectLinked();
+                		        if (count($exp->linkedObjectsIds['commande']) > 0)
+                		        {
+                		            foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
+                		            {
+                		                $originforcontact = 'commande';
+                		                $originidforcontact = $value->id;
+                		                break; // We take first one
+                		            }
+                		        }
+                		    }
+
+                		    $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
+                		    $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
+
+                		    $resqlcontact = $this->db->query($sqlcontact);
+                		    if ($resqlcontact)
+                		    {
+                		        while($objcontact = $this->db->fetch_object($resqlcontact))
+                		        {
+        					        //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
+                		            $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
+                		        }
+                		    }
+                		    else dol_print_error($resqlcontact);
+                		}
                     }
 
                     if (! $error)
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 61f51b19436..e02ec4541ef 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -409,7 +409,7 @@ class Facture extends CommonInvoice
 			{
 				foreach($this->linked_objects as $origin => $tmp_origin_id)
 				{
-				    if (is_array($tmp_origin_id))       // New baheviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
+				    if (is_array($tmp_origin_id))       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
 				    {
 				        foreach($tmp_origin_id as $origin_id)
 				        {
@@ -431,43 +431,43 @@ class Facture extends CommonInvoice
     						$error++;
     					}
 				    }
-				    
-					if (! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN))
-					{
-    					$originforcontact = $origin;
-    					$originidforcontact = $origin_id;
-    					if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
-    					{
-    					    require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
-    					    $exp = new Expedition($this->db);
-    					    $exp->fetch($origin_id);
-    					    $exp->fetchObjectLinked();
-    					    if (count($exp->linkedObjectsIds['commande']) > 0) 
-    					    {
-    					        foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
-    					        {
-    					            $originforcontact = 'commande';
-    					            $originidforcontact = $value->id;
-    					            break; // We take first one
-    					        }
-    					    }
-    					}
-    					
-    					$sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
-    					$sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
+				}
+			}
 			
-    					$resqlcontact = $this->db->query($sqlcontact);
-    					if ($resqlcontact)
-    					{
-    					    while($objcontact = $this->db->fetch_object($resqlcontact))
-    					    {
-    					        //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
-    					        $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
-    					    }
-    					}
-    					else dol_print_error($resqlcontact);
-					}
+			if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id))   // Get contact from origin object
+			{
+				$originforcontact = $this->origin;
+				$originidforcontact = $this->origin_id;
+				if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
+				{
+				    require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
+				    $exp = new Expedition($this->db);
+				    $exp->fetch($this->origin_id);
+				    $exp->fetchObjectLinked();
+				    if (count($exp->linkedObjectsIds['commande']) > 0) 
+				    {
+				        foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
+				        {
+				            $originforcontact = 'commande';
+				            $originidforcontact = $value->id;
+				            break; // We take first one
+				        }
+				    }
+				}
+				
+				$sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
+				$sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
+	
+				$resqlcontact = $this->db->query($sqlcontact);
+				if ($resqlcontact)
+				{
+				    while($objcontact = $this->db->fetch_object($resqlcontact))
+				    {
+				        //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
+				        $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
+				    }
 				}
+				else dol_print_error($resqlcontact);
 			}
 
 			/*
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index 75100aae9e6..a8f84731650 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -934,55 +934,71 @@ class Contrat extends CommonObject
 			if (! $error)
 			{
     			// Add object linked
-    			if (is_array($this->linked_objects) && ! empty($this->linked_objects))
+    			if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
     			{
-    			    foreach($this->linked_objects as $origin => $origin_id)
+    			    foreach($this->linked_objects as $origin => $tmp_origin_id)
     			    {
-    			        $ret = $this->add_object_linked($origin, $origin_id);
-    			        if (! $ret)
+    			        if (is_array($tmp_origin_id))       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
     			        {
-    			            dol_print_error($this->db);
-    			            $error++;
+    			            foreach($tmp_origin_id as $origin_id)
+    			            {
+    			                $ret = $this->add_object_linked($origin, $origin_id);
+    			                if (! $ret)
+    			                {
+    			                    dol_print_error($this->db);
+    			                    $error++;
+    			                }
+    			            }
     			        }
+    			        else                                // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
+    			        {
+    			            $origin_id = $tmp_origin_id;
+    			            $ret = $this->add_object_linked($origin, $origin_id);
+    			            if (! $ret)
+    			            {
+    			                dol_print_error($this->db);
+    			                $error++;
+    			            }
+    			        }
+    			    }
+    			}
 
-            			if (! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN))
-            			{
-            			    $originforcontact = $origin;
-            			    $originidforcontact = $origin_id;
-            			    if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
-            			    {
-            			        require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
-            			        $exp = new Expedition($db);
-            			        $exp->fetch($origin_id);
-            			        $exp->fetchObjectLinked();
-            			        if (count($exp->linkedObjectsIds['commande']) > 0)
-            			        {
-            			            foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
-            			            {
-            			                $originforcontact = 'commande';
-            			                $originidforcontact = $value->id;
-            			                break; // We take first one
-            			            }
-            			        }
-            			    }
-
-            			    $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
-            			    $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
-
-            			    $resqlcontact = $this->db->query($sqlcontact);
-            			    if ($resqlcontact)
-            			    {
-            			        while($objcontact = $this->db->fetch_object($resqlcontact))
-            			        {
-            			            if ($objcontact->source == 'internal' && in_array($objcontact->code, array('SALESREPSIGN', 'SALESREPFOLL'))) continue;    // ignore this, already forced previously
-
-            			            //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
-            			            $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
-            			        }
-            			    }
-            			    else dol_print_error($resqlcontact);
-            			}
+    			if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id))   // Get contact from origin object
+    			{
+    			    $originforcontact = $this->origin;
+    			    $originidforcontact = $this->origin_id;
+    			    if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
+    			    {
+    			        require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
+    			        $exp = new Expedition($db);
+    			        $exp->fetch($this->origin_id);
+    			        $exp->fetchObjectLinked();
+    			        if (count($exp->linkedObjectsIds['commande']) > 0)
+    			        {
+    			            foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
+    			            {
+    			                $originforcontact = 'commande';
+    			                $originidforcontact = $value->id;
+    			                break; // We take first one
+    			            }
+    			        }
+    			    }
+
+    			    $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
+    			    $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
+
+    			    $resqlcontact = $this->db->query($sqlcontact);
+    			    if ($resqlcontact)
+    			    {
+    			        while($objcontact = $this->db->fetch_object($resqlcontact))
+    			        {
+    			            if ($objcontact->source == 'internal' && in_array($objcontact->code, array('SALESREPSIGN', 'SALESREPFOLL'))) continue;    // ignore this, already forced previously
+
+    			            //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
+    			            $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
+    			        }
     			    }
+    			    else dol_print_error($resqlcontact);
     			}
 			}
 
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index ca1468b3b09..9ee5510f983 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -487,5 +487,5 @@ ToCreateARecurringInvoiceGene=To generate future invoices regularly and manually
 ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask you administrator to enable and setup module <strong>%s</strong>. Note that both method (manual and automatic) can be used together with no risk of duplication.
 DeleteRepeatableInvoice=Delete template invoice
 ConfirmDeleteRepeatableInvoice=Are your sure you want to delete the template invoice?
-CreateOneBillByThird=Create one invoice per third (otherwise, one invoice per order)
+CreateOneBillByThird=Create one invoice per third party (otherwise, one invoice per order)
 BillCreated=%s bill(s) created
-- 
GitLab