From d48f2945310af984f175af2f0a61de9b1441ad2d Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Sat, 15 Sep 2012 15:33:00 +0200
Subject: [PATCH] New: [ task #289 ] Reorder tasks

---
 ChangeLog                                |  1 +
 htdocs/core/ajax/row.php                 | 30 ++++++++++++++++--------
 htdocs/core/class/commonobject.class.php | 23 ++++++++++++++----
 htdocs/core/lib/project.lib.php          |  2 +-
 htdocs/core/tpl/ajaxrow.tpl.php          |  1 +
 htdocs/projet/class/project.class.php    | 14 ++++++-----
 htdocs/projet/class/task.class.php       | 17 +++++++-------
 htdocs/projet/tasks.php                  |  2 +-
 8 files changed, 58 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2e06735cb7d..2dcfde3a4d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@ English Dolibarr ChangeLog
 
 ***** ChangeLog for 3.3 compared to 3.2.2 *****
 For users:
+- New: [ task #289 ] Can reorder tasks.
 - New: Add field "signature" into thirdparty card. If filled, text is added 
   at end of predefined email texts. If option MAIL_DO_NOT_USE_SIGN is on, this
   feature is disabled.
diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php
index 69212205832..647b39510b2 100644
--- a/htdocs/core/ajax/row.php
+++ b/htdocs/core/ajax/row.php
@@ -43,21 +43,31 @@ print '<!-- Ajax page called with url '.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY
 if ((isset($_POST['roworder']) && ! empty($_POST['roworder'])) && (isset($_POST['table_element_line']) && ! empty($_POST['table_element_line']))
 	&& (isset($_POST['fk_element']) && ! empty($_POST['fk_element'])) && (isset($_POST['element_id']) && ! empty($_POST['element_id'])) )
 {
-	$roworder = explode(',',GETPOST('roworder','alpha',2));
+	$roworder=GETPOST('roworder','alpha',2);
+	$table_element_line=GETPOST('table_element_line','alpha',2);
+	$fk_element=GETPOST('fk_element','alpha',2);
+	$element_id=GETPOST('element_id','int',2);
 
-	foreach($roworder as $value)
+	dol_syslog("AjaxRow roworder=".$roworder." table_element_line=".$table_element_line." fk_element=".$fk_element." element_id=".$element_id, LOG_DEBUG);
+
+	$rowordertab = explode(',',$roworder);
+	foreach($rowordertab as $value)
 	{
-		if (! empty($value)) $newroworder[] = $value;
+		if (! empty($value)) $newrowordertab[] = $value;
 	}
 
-	dol_syslog("AjaxRow roworder=".GETPOST('roworder','alpha',2)." fk_element=".GETPOST('fk_element','int',2), LOG_DEBUG);
-
 	$row=new GenericObject($db);
-	$row->table_element_line = GETPOST('table_element_line','alpha',2);
-	$row->fk_element = GETPOST('fk_element','int',2);
-	$row->id = GETPOST('element_id','int',2);
-	$result=$row->line_ajaxorder($newroworder);
-	$result=$row->line_order(true);
+	$row->table_element_line = $table_element_line;
+	$row->fk_element = $fk_element;
+	$row->id = $element_id;
+	$result=$row->line_ajaxorder($newrowordertab);
+
+	// Reorder line to have position of chilren lines sharing same counter than parent lines
+	// This should be useless because there is no need to have children sharing same counter that parent.
+	if (in_array($fk_element,array('fk_facture','fk_propal','fk_commande')))
+	{
+		$result=$row->line_order(true);
+	}
 }
 
 ?>
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 29e58b35135..0b2c8acf531 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -1019,7 +1019,9 @@ abstract class CommonObject
 
 
     /**
-     *  Stocke un numero de rang pour toutes les lignes de detail d'un element qui n'en ont pas.
+     *  Save a new position (field rang) for details lines.
+     *  You can choose to ser position for lines with already a position or lines wihtout any position defined.
+     *  Call this function only for table that contains a field fk_parent_line.
      *
      * 	@param		boolean		$renum			true to renum all already ordered lines, false to renum only not already ordered lines.
      * 	@param		string		$rowidorder		ASC or DESC
@@ -1038,7 +1040,9 @@ abstract class CommonObject
             return -1;
         }
 
-		$sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
+        // Count number of lines to reorder (according to choice $renum)
+    	$nl=0;
+        $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
 		$sql.= ' WHERE '.$this->fk_element.'='.$this->id;
 		if (! $renum) $sql.= ' AND rang = 0';
 		if ($renum) $sql.= ' AND rang <> 0';
@@ -1050,16 +1054,20 @@ abstract class CommonObject
 			$row = $this->db->fetch_row($resql);
 			$nl = $row[0];
 		}
+		else dol_print_error($this->db);
 		if ($nl > 0)
 		{
+			// The goal of this part is to reorder all lines, with all children lines sharing the same
+			// counter that parents.
 			$rows=array();
 
+			// We frist search all lines that are parent lines (for multilevel details lines)
 			$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
 			$sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
 			$sql.= ' AND fk_parent_line IS NULL';
 			$sql.= ' ORDER BY rang ASC, rowid '.$rowidorder;
 
-			dol_syslog(get_class($this)."::line_order sql=".$sql, LOG_DEBUG);
+			dol_syslog(get_class($this)."::line_order search all parent lines sql=".$sql, LOG_DEBUG);
 			$resql = $this->db->query($sql);
 			if ($resql)
 			{
@@ -1068,7 +1076,7 @@ abstract class CommonObject
 				while ($i < $num)
 				{
 					$row = $this->db->fetch_row($resql);
-					$rows[] = $row[0];
+					$rows[] = $row[0];	// Add parent line into array rows
 					$childrens = $this->getChildrensOfLine($row[0]);
 					if (! empty($childrens))
 					{
@@ -1080,6 +1088,7 @@ abstract class CommonObject
 					$i++;
 				}
 
+				// Now we set a new number for each lines (parent and children with children included into parent tree)
 				if (! empty($rows))
 				{
 					foreach($rows as $key => $row)
@@ -1088,6 +1097,10 @@ abstract class CommonObject
 					}
 				}
 			}
+			else
+			{
+				dol_print_error($this->db);
+			}
 		}
 	}
 
@@ -1106,7 +1119,7 @@ abstract class CommonObject
 		$sql.= ' AND fk_parent_line = '.$id;
 		$sql.= ' ORDER BY rang ASC';
 
-		dol_syslog(get_class($this)."::getChildrenOfLines sql=".$sql, LOG_DEBUG);
+		dol_syslog(get_class($this)."::getChildrenOfLines search children lines for line ".$id." sql=".$sql, LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql)
 		{
diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
index 563d3b638e0..e5dddb11ea5 100644
--- a/htdocs/core/lib/project.lib.php
+++ b/htdocs/core/lib/project.lib.php
@@ -326,7 +326,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
                     $lastprojectid=$lines[$i]->fk_project;
                 }
 
-                print "<tr ".$bc[$var].">\n";
+                print '<tr '.$bc[$var].' id="row-'.$lines[$i]->id.'">'."\n";
 
                 // Project
                 if ($showproject)
diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php
index 0745bc20959..62b4b929b7f 100644
--- a/htdocs/core/tpl/ajaxrow.tpl.php
+++ b/htdocs/core/tpl/ajaxrow.tpl.php
@@ -26,6 +26,7 @@ $fk_element=$object->fk_element;
 $table_element_line=$object->table_element_line;
 $nboflines=(isset($object->lines)?count($object->lines):(isset($tasksarray)?count($tasksarray):0));
 $forcereloadpage=$conf->global->MAIN_FORCE_RELOAD_PAGE;
+
 if (GETPOST('action') != 'editline' && $nboflines > 1) { ?>
 <script type="text/javascript">
 $(document).ready(function(){
diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
index c68d1d6efac..9f01817a1dd 100644
--- a/htdocs/projet/class/project.class.php
+++ b/htdocs/projet/class/project.class.php
@@ -1,7 +1,7 @@
 <?php
 
 /* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2005-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2005-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2010 Regis Houssin        <regis@dolibarr.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,19 +21,21 @@
 /**
  * 		\file       htdocs/projet/class/project.class.php
  * 		\ingroup    projet
- * 		\brief      Fichier de la classe de gestion des projets
+ * 		\brief      File of class to manage projects
  */
 require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
 
 /**
- * 		\class      Project
- * 		\brief      Class to manage projects
+ *	Class to manage projects
  */
 class Project extends CommonObject
 {
 
     public $element = 'project';    //!< Id that identify managed objects
     public $table_element = 'projet';  //!< Name of table without prefix where object is stored
+    public $table_element_line = 'projet_task';
+    public $fk_element = 'fk_projet';
+
     var $id;
     var $ref;
     var $description;
@@ -208,7 +210,7 @@ class Project extends CommonObject
                     }
                     // End call triggers
                 }
-                
+
                 if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref))
                 {
                 	// We remove directory
@@ -1205,7 +1207,7 @@ class Project extends CommonObject
 		    	}
 	    	}
 			//print "$this->date_start + $tasktoshiftdate->date_start - $old_project_dt_start";exit;
-			
+
 	    	//Calcultate new task start date with difference between old proj start date and origin task start date
 	    	if (!empty($tasktoshiftdate->date_start))
 	    	{
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index 40601aeef08..d4604174ec5 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2008-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
- * Copyright (C) 2010_2012	Regis Houssin		<regis@dolibarr.fr>
+ * Copyright (C) 2010-2012	Regis Houssin		<regis@dolibarr.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
@@ -26,9 +26,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
 
 
 /**
- *      \class      Task
- *      \brief      Class to manage tasks
- *		\remarks	Initialy built by build_class_from_table on 2008-09-10 12:41
+ * 	Class to manage tasks
+ *	Initialy built by build_class_from_table on 2008-09-10 12:41
  */
 class Task extends CommonObject
 {
@@ -479,7 +478,7 @@ class Task extends CommonObject
 
     /**
      * Return list of tasks for all projects or for one particular project
-     * Sort order is on project, TODO then of position of task, and last on title of first level task
+     * Sort order is on project, then on position of task, and last on title of first level task
      *
      * @param	User	$usert				Object user to limit tasks affected to a particular user
      * @param	User	$userp				Object user to limit projects of a particular user and public projects
@@ -519,10 +518,10 @@ class Task extends CommonObject
             if ($projectid) $sql.= " AND p.rowid in (".$projectid.")";
         }
         if ($filteronprojref) $sql.= " AND p.ref LIKE '%".$filteronprojref."%'";
-        $sql.= " ORDER BY p.ref, t.label";
+        $sql.= " ORDER BY p.ref, t.rang, t.label";
 
         //print $sql;
-        dol_syslog("Task::getTasksArray sql=".$sql, LOG_DEBUG);
+        dol_syslog(get_class($this)."::getTasksArray sql=".$sql, LOG_DEBUG);
         $resql = $this->db->query($sql);
         if ($resql)
         {
@@ -593,7 +592,7 @@ class Task extends CommonObject
     {
         $arrayroles = array();
 
-        dol_syslog("Task::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid);
+        dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid);
 
         // We want role of user for a projet or role of user for a task. Both are not possible.
         if (empty($userp) && empty($usert))
@@ -633,7 +632,7 @@ class Task extends CommonObject
         }
         //print $sql;
 
-        dol_syslog("Task::getUserRolesForProjectsOrTasks sql=".$sql);
+        dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks sql=".$sql);
         $resql = $this->db->query($sql);
         if ($resql)
         {
diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php
index 26390e0c2bd..ec6257e7854 100644
--- a/htdocs/projet/tasks.php
+++ b/htdocs/projet/tasks.php
@@ -355,7 +355,7 @@ else
 	//var_dump($tasksrole);
 
 	if (! empty($conf->use_javascript_ajax))
-	{
+	{
 		include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
 	}
 
-- 
GitLab