diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index d11a37564b9..6af44d4a7d6 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -292,10 +292,12 @@ if ($resql) } if (! empty($moreforfilter)) { - print ''; - print ''; - print $moreforfilter; - print ''; + print '
'; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; } print ''; @@ -305,6 +307,9 @@ if ($resql) print_liste_field_titre($langs->trans('OrderDate'),$_SERVER["PHP_SELF"],'c.date_commande','',$param, 'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('DeliveryDate'),$_SERVER["PHP_SELF"],'c.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'c.total_ht','',$param, 'align="right"',$sortfield,$sortorder); + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'c.fk_statut','',$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); print ''; diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index c4908595493..fa9db9ea4b4 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -220,7 +220,7 @@ abstract class DoliDB implements Database /** * Define sort criteria of request * - * @param string $sortfield List of sort fields + * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda, t2.fieldb' * @param string $sortorder Sort order * @return string String to provide syntax of a sort sql string */ @@ -236,7 +236,8 @@ abstract class DoliDB implements Database else $return.=','; $return.=preg_replace('/[^0-9a-z_\.]/i','',$val); - if (isset($sortorder)) { + if (isset($sortorder)) + { $return.=' '.preg_replace('/[^0-9a-z]/i','',$sortorder); } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ed3d709f16f..5d75d7ad5d6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4644,7 +4644,8 @@ function dol_osencode($str) /** - * Return an id or code from a code or id. Store also Code-Id into a cache for next use. + * Return an id or code from a code or id. + * Store also Code-Id into a cache to speed up next request on same key. * * @param DoliDB $db Database handler * @param string $key Code to get Id diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 3709303f68e..c337cccc940 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -872,13 +872,15 @@ function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole) * Return HTML table with list of projects and number of opened tasks * * @param DoliDB $db Database handler + * @param Form $form Object form * @param int $socid Id thirdparty * @param int $projectsListId Id of project i have permission on * @param int $mytasks Limited to task i am contact to * @param int $statut -1=No filter on statut, 0 or 1 = Filter on status + * @param array $listofoppstatus List of opportunity status * @return void */ -function print_projecttasks_array($db, $socid, $projectsListId, $mytasks=0, $statut=-1) +function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks=0, $statut=-1, $listofoppstatus=array()) { global $langs,$conf,$user,$bc; @@ -890,18 +892,22 @@ function print_projecttasks_array($db, $socid, $projectsListId, $mytasks=0, $sta $sortorder=''; $project_year_filter=0; - $title=$langs->trans("Project"); - if (strcmp($statut, '') && $statut >= 0) $title=$langs->trans("Project").' ('.$langs->trans($projectstatic->statuts_long[$statut]).')'; + $title=$langs->trans("Projects"); + if (strcmp($statut, '') && $statut >= 0) $title=$langs->trans("Projects").' '.$langs->trans($projectstatic->statuts_long[$statut]); print ''; print ''; print_liste_field_titre($title,"index.php","","","","",$sortfield,$sortorder); - //if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) print_liste_field_titre($langs->trans("OpportunityStatus"),"","","","",'align="right"',$sortfield,$sortorder); + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + print_liste_field_titre($langs->trans("OpportunityAmount"),"","","","",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("OpportunityStatus"),"","","","",'align="right"',$sortfield,$sortorder); + } if (empty($conf->global->PROJECT_HIDE_TASKS)) print_liste_field_titre($langs->trans("Tasks"),"","","","",'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),"","","","",'align="right"',$sortfield,$sortorder); print "\n"; - $sql = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, COUNT(t.rowid) as nb"; + $sql = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_amount, COUNT(DISTINCT t.rowid) as nb"; // We use DISTINCT here because line can be doubled if task has 2 links to same user $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if ($mytasks) { @@ -928,24 +934,31 @@ function print_projecttasks_array($db, $socid, $projectsListId, $mytasks=0, $sta { $sql.= " AND p.fk_statut = ".$statut; } - if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE)) { + if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE)) + { $project_year_filter = GETPOST("project_year_filter"); //Check if empty or invalid year. Wildcard ignores the sql check - if ($project_year_filter != "*") { - if (empty($project_year_filter) || !ctype_digit($project_year_filter)) { // + if ($project_year_filter != "*") + { + if (empty($project_year_filter) || !ctype_digit($project_year_filter)) + { $project_year_filter = date("Y"); } $sql.= " AND (p.dateo IS NULL OR p.dateo <= ".$db->idate(dol_get_last_day($project_year_filter,12,false)).")"; $sql.= " AND (p.datee IS NULL OR p.datee >= ".$db->idate(dol_get_first_day($project_year_filter,1,false)).")"; } } - $sql.= " GROUP BY p.rowid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status"; + $sql.= " GROUP BY p.rowid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount"; $sql.= " ORDER BY p.title, p.ref"; $var=true; $resql = $db->query($sql); if ( $resql ) { + $total_task = 0; + $total_opp_amount = 0; + $ponderated_opp_amount = 0; + $num = $db->num_rows($resql); $i = 0; @@ -967,22 +980,34 @@ function print_projecttasks_array($db, $socid, $projectsListId, $mytasks=0, $sta $projectstatic->ref=$objp->ref; print $projectstatic->getNomUrl(1); print ' - '.dol_trunc($objp->title,24).''; - /*if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { print ''; + print ''; - }*/ - if (empty($conf->global->PROJECT_HIDE_TASKS)) print ''; + } $projectstatic->statut = $objp->status; + if (empty($conf->global->PROJECT_HIDE_TASKS)) print ''; print ''; print "\n"; + + $total_task = $total_task + $objp->nb; + $total_opp_amount = $total_opp_amount + $objp->opp_amount; + $ponderated_opp_amount = $ponderated_opp_amount + price2num($listofoppstatus[$objp->opp_status] * $objp->opp_amount / 100); } $i++; } + print '"; + print ''; + print ''; + if (empty($conf->global->PROJECT_HIDE_TASKS)) print ''; + $db->free($resql); } else diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 5d560ed4a24..09ac5dd44a7 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -26,6 +26,8 @@ ConfirmDeleteATask=Are you sure you want to delete this task ? OfficerProject=Officer project LastProjects=Last %s projects AllProjects=All projects +OpenedProjects=Opened projects +OpportunitiesStatusForOpenedProjects=Opportunities status for opened projects ProjectsList=List of projects ShowProject=Show project SetProject=Set project @@ -78,6 +80,8 @@ ListDonationsAssociatedProject=List of donations associated with the project ListActionsAssociatedProject=List of events associated with the project ListTaskTimeUserProject=List of time consumed on tasks of project TaskTimeUserProject=Time consumed on tasks of project +ActivityOnProjectToday=Activity on project today +ActivityOnProjectYesterday=Activity on project yesterday ActivityOnProjectThisWeek=Activity on project this week ActivityOnProjectThisMonth=Activity on project this month ActivityOnProjectThisYear=Activity on project this year @@ -93,6 +97,7 @@ ReOpenAProject=Open project ConfirmReOpenAProject=Are you sure you want to re-open this project ? ProjectContact=Project contacts ActionsOnProject=Events on project +OpenedProjects=Opened projects YouAreNotContactOfProject=You are not a contact of this private project DeleteATimeSpent=Delete time spent ConfirmDeleteATimeSpent=Are you sure you want to delete this time spent ? @@ -142,6 +147,7 @@ PlannedWorkloadShort=Workload WorkloadOccupation=Workload assignation ProjectReferers=Refering objects SearchAProject=Search a project +SearchATask=Search a task ProjectMustBeValidatedFirst=Project must be validated first ProjectDraft=Draft projects FirstAddRessourceToAllocateTime=Associate a resource to allocate time @@ -161,3 +167,5 @@ ManageOpportunitiesStatus=Use projects to follow leads/opportinuties ProjectNbProjectByMonth=Nb of created projects by month ProjectsStatistics=Statistics on projects/leads TaskAssignedToEnterTime=Task assigned. Entering time on this task should be possible. +OpenedProjectsByThirdparties=Opened projects by thirdparties +OpportunityPonderatedAmount=Opportunities ponderated amount \ No newline at end of file diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php index 75fd12e9d95..39f728263ad 100644 --- a/htdocs/projet/activity/index.php +++ b/htdocs/projet/activity/index.php @@ -49,6 +49,7 @@ $now = dol_now(); $projectstatic=new Project($db); $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); // Return all projects I have permission on because I want my tasks and some of my task may be on a public projet that is not my project +$tasktmp=new Task($db); $title=$langs->trans("Activities"); if ($mine) $title=$langs->trans("MyActivities"); @@ -68,13 +69,31 @@ else print '
'; -print_projecttasks_array($db,$socid,$projectsListId,$mine,1); +// Search task +if (! empty($conf->projet->enabled) && $user->rights->projet->lire) +{ + $var=false; + print '
'; + print ''; + print ''; + print ''; // All status + print '
'; + if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency); + print ''; $code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); if ($code) print $langs->trans("OppStatus".$code); print ''.$objp->nb.''.$objp->nb.''.$projectstatic->getLibStatut(3).'
'.$langs->trans("Total")."'.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).''.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmount"), 1).''.$total_task.'
'; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print "
'.$langs->trans("SearchATask").'
:
:
:
\n"; + print "
\n"; +} /* Affichage de la liste des projets d'aujourd'hui */ print '
'; print ''; -print ''; +print ''; print ''; print "\n"; @@ -127,67 +146,64 @@ print "
'.$langs->trans('Today').''.$langs->trans('ActivityOnProjectToday').''.$langs->trans("Time").'
"; if ($db->type != 'pgsql') { -/* Affichage de la liste des projets d'hier */ -print '
'; -print ''; -print ''; -print ''; -print "\n"; + /* Affichage de la liste des projets d'hier */ + print '
'.$langs->trans('Yesterday').''.$langs->trans("Time").'
'; + print ''; + print ''; + print ''; + print "\n"; -$sql = "SELECT p.rowid, p.ref, p.title, sum(tt.task_duration) as nb"; -$sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; -$sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; -$sql.= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; -$sql.= " WHERE t.fk_projet = p.rowid"; -$sql.= " AND p.entity = ".$conf->entity; -$sql.= " AND tt.fk_task = t.rowid"; -$sql.= " AND tt.fk_user = ".$user->id; -$sql.= " AND date_format(date_add(task_date, INTERVAL 1 DAY),'%y-%m-%d') = '".strftime("%y-%m-%d",$now)."'"; -$sql.= " AND p.rowid in (".$projectsListId.")"; -$sql.= " GROUP BY p.rowid, p.ref, p.title"; + $sql = "SELECT p.rowid, p.ref, p.title, sum(tt.task_duration) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; + $sql.= " WHERE t.fk_projet = p.rowid"; + $sql.= " AND p.entity = ".$conf->entity; + $sql.= " AND tt.fk_task = t.rowid"; + $sql.= " AND tt.fk_user = ".$user->id; + $sql.= " AND date_format(date_add(task_date, INTERVAL 1 DAY),'%y-%m-%d') = '".strftime("%y-%m-%d",$now)."'"; + $sql.= " AND p.rowid in (".$projectsListId.")"; + $sql.= " GROUP BY p.rowid, p.ref, p.title"; -$resql = $db->query($sql); -if ( $resql ) -{ - $var=true; - $total=0; - - while ($row = $db->fetch_object($resql)) + $resql = $db->query($sql); + if ( $resql ) { - $var=!$var; - print ""; - print ''; - print ''; - print "\n"; - $total += $row->nb; + $var=true; + $total=0; + + while ($row = $db->fetch_object($resql)) + { + $var=!$var; + print ""; + print ''; + print ''; + print "\n"; + $total += $row->nb; + } + + $db->free($resql); } - - $db->free($resql); + else + { + dol_print_error($db); + } + print ''; + print ''; + print ''; + print "\n"; + print "
'.$langs->trans('ActivityOnProjectYesterday').''.$langs->trans("Time").'
'; - $projectstatic->id=$row->rowid; - $projectstatic->ref=$row->ref; - $projectstatic->title=$row->title; - print $projectstatic->getNomUrl(1, '', 1); - print ''.convertSecondToTime($row->nb).'
'; + $projectstatic->id=$row->rowid; + $projectstatic->ref=$row->ref; + $projectstatic->title=$row->title; + print $projectstatic->getNomUrl(1, '', 1); + print ''.convertSecondToTime($row->nb).'
'.$langs->trans('Total').''.convertSecondToTime($total).'
"; } -else -{ - dol_print_error($db); -} -print ''; -print ''.$langs->trans('Total').''; -print ''.convertSecondToTime($total).''; -print "\n"; -print ""; - -} - - -print '
'; // TODO Do not use week function to be compatible with all database if ($db->type != 'pgsql') { +print '
'; /* Affichage de la liste des projets de la semaine */ print ''; @@ -293,52 +309,190 @@ print "\n"; print "
"; /* Affichage de la liste des projets de l'annee */ -print '
'; -print ''; -print ''; -print ''; -print "\n"; - -$sql = "SELECT p.rowid, p.ref, p.title, SUM(tt.task_duration) as nb"; -$sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; -$sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; -$sql.= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; -$sql.= " WHERE t.fk_projet = p.rowid"; -$sql.= " AND p.entity = ".$conf->entity; -$sql.= " AND tt.fk_task = t.rowid"; -$sql.= " AND tt.fk_user = ".$user->id; -$sql.= " AND YEAR(task_date) = '".strftime("%Y",$now)."'"; -$sql.= " AND p.rowid in (".$projectsListId.")"; -$sql.= " GROUP BY p.rowid, p.ref, p.title"; - -$var=false; -$resql = $db->query($sql); -if ( $resql ) +if (! empty($conf->global->PROJECT_TASK_TIME_YEAR)) { - while ($row = $db->fetch_object($resql)) + print '
'.$langs->trans("ActivityOnProjectThisYear").': '.strftime("%Y", $now).''.$langs->trans("Time").'
'; + print ''; + print ''; + print ''; + print "\n"; + + $sql = "SELECT p.rowid, p.ref, p.title, SUM(tt.task_duration) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; + $sql.= " WHERE t.fk_projet = p.rowid"; + $sql.= " AND p.entity = ".$conf->entity; + $sql.= " AND tt.fk_task = t.rowid"; + $sql.= " AND tt.fk_user = ".$user->id; + $sql.= " AND YEAR(task_date) = '".strftime("%Y",$now)."'"; + $sql.= " AND p.rowid in (".$projectsListId.")"; + $sql.= " GROUP BY p.rowid, p.ref, p.title"; + + $var=false; + $resql = $db->query($sql); + if ( $resql ) { - print ""; - print ''; - print ''; - print "\n"; - $var=!$var; + while ($row = $db->fetch_object($resql)) + { + print ""; + print ''; + print ''; + print "\n"; + $var=!$var; + } + $db->free($resql); } - $db->free($resql); + else + { + dol_print_error($db); + } + print ''; + print ''; + print ''; + print "\n"; + print "
'.$langs->trans("ActivityOnProjectThisYear").': '.strftime("%Y", $now).''.$langs->trans("Time").'
'; - $projectstatic->id=$row->rowid; - $projectstatic->ref=$row->ref; - $projectstatic->title=$row->title; - print $projectstatic->getNomUrl(1, '', 1); - print ''.convertSecondToTime($row->nb).'
'; + $projectstatic->id=$row->rowid; + $projectstatic->ref=$row->ref; + $projectstatic->title=$row->title; + print $projectstatic->getNomUrl(1, '', 1); + print ''.convertSecondToTime($row->nb).'
'.$langs->trans('Total').''.convertSecondToTime($total).'
"; } -else + + + +print '
'; + + +if (empty($conf->global->PROJECT_HIDE_TASKS)) { - dol_print_error($db); + // Tasks for all resources of all opened projects and time spent for each task/resource + + $max = (empty($conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA)?1000:$conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA); + + $sql = "SELECT p.ref, p.title, p.rowid as projectid, p.fk_statut as status, p.fk_opp_status as opp_status, t.label, t.rowid as taskid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee, SUM(tasktime.task_duration) as timespent"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tasktime on tasktime.fk_task = t.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on tasktime.fk_user = u.rowid"; + $sql.= " WHERE p.entity = ".$conf->entity; + if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")"; + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + $sql.= " AND p.fk_statut=1"; + $sql.= " GROUP BY p.ref, p.title, p.rowid, t.label, t.rowid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee"; + $sql.= " ORDER BY t.dateo desc, t.rowid desc, t.datee"; + $sql.= $db->plimit($max+1); // We want more to know if we have more than limit + + $var=true; + + dol_syslog('projet:index.php: affectationpercent', LOG_DEBUG); + $resql = $db->query($sql); + if ( $resql ) + { + $num = $db->num_rows($resql); + $i = 0; + + //print_fiche_titre($langs->trans("TasksOnOpenedProject"),'','').'
'; + + print ''; + print ''; + //print ''; + print ''; + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + while ($i < $num && $i < $max) + { + $obj = $db->fetch_object($resql); + $var=!$var; + + $username=''; + if ($obj->userid && $userstatic->id != $obj->userid) // We have a user and it is not last loaded user + { + $result=$userstatic->fetch($obj->userid); + if (! $result) $userstatic->id=0; + } + if ($userstatic->id) $username = $userstatic->getNomUrl(0,0); + + print ""; + //print ''; + print ''; + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + $i++; + } + + if ($num > $max) + { + $colspan=6; + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) $colspan++; + print ''; + } + + print "
'.$langs->trans('TaskRessourceLinks').''.$langs->trans('OpenedProjects').''.$langs->trans('OpportunityStatus').''.$langs->trans('Task').''.$langs->trans('DateStart').''.$langs->trans('DateEnd').''.$langs->trans('PlannedWorkload').''.$langs->trans("ProgressDeclared").''; + print ''.$langs->trans('TimeSpent').''.$langs->trans("ProgressCalculated").''; + print '
'.$username.''; + $projectstatic->id=$obj->projectid; + $projectstatic->ref=$obj->ref; + $projectstatic->title=$obj->title; + print $projectstatic->getNomUrl(1,'',16,'','
'); + //print ''.$obj->title.''; + print '
'; + $code = dol_getIdFromCode($db, $obj->opp_status, 'c_lead_status', 'rowid', 'code'); + if ($code) print $langs->trans("OppStatus".$code); + print ''; + if (! empty($obj->taskid)) + { + $tasktmp->id = $obj->taskid; + $tasktmp->ref = $obj->ref; + $tasktmp->label = $obj->label; + print $tasktmp->getNomUrl(1,'withproject','task',1,'
'); + } + else print $langs->trans("NoTasks"); + print '
'.dol_print_date($db->jdate($obj->dateo),'day').''.dol_print_date($db->jdate($obj->datee),'day').''; + print convertSecondToTime($obj->planned_workload, 'all'); + print ''; + print ($obj->taskid>0)?$obj->progress.'%':''; + print ''; + print convertSecondToTime($obj->timespent, 'all'); + print ''; + if (! empty($obj->taskid)) + { + if (empty($obj->planned_workload) > 0) { + $percentcompletion = $langs->trans("WorkloadNotDefined"); + } else { + $percentcompletion = intval($obj->duration_effective*100/$obj->planned_workload).'%'; + } + } + print $percentcompletion; + print '
'.$langs->trans("WarningTooManyDataPleaseUseMoreFilters").'
"; + + + $db->free($resql); + } + else + { + dol_print_error($db); + } + } -print ''; -print ''.$langs->trans('Total').''; -print ''.convertSecondToTime($total).''; -print "\n"; -print ""; print '
'; diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 7a38e7a1278..0bf57ebb922 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -871,10 +871,11 @@ class Project extends CommonObject * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param string $option Variant ('', 'nolink') * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string - * @param string $moreinpopup Text to add into popu + * @param string $moreinpopup Text to add into popup + * @param string $sep Separator between ref and label if option addlabel is set * @return string Chaine avec URL */ - function getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='') + function getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='', $sep=' - ') { global $langs; @@ -905,7 +906,7 @@ class Project extends CommonObject if ($withpicto) $result.=($link . img_object($label, $picto, 'class="classfortooltip"') . $linkend); if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link . $this->ref . $linkend . (($addlabel && $this->title) ? ' - ' . dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) : ''); + if ($withpicto != 2) $result.=$link . $this->ref . $linkend . (($addlabel && $this->title) ? $sep . dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) : ''); return $result; } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index bd20a930aa4..5bdbc4a1820 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -499,9 +499,11 @@ class Task extends CommonObject * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param string $option 'withproject' or '' * @param string $mode Mode 'task', 'time', 'contact', 'note', document' define page to link to. + * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string + * @param string $sep Separator between ref and label if option addlabel is set * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$option='',$mode='task') + function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ') { global $langs; @@ -525,7 +527,7 @@ class Task extends CommonObject if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link.$this->ref.$linkend; + if ($withpicto != 2) $result.=$link.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); return $result; } @@ -585,12 +587,14 @@ class Task extends CommonObject $sql.= " WHERE p.entity = ".$conf->entity; $sql.= " AND t.fk_projet = p.rowid"; } - if ($mode == 1) + elseif ($mode == 1) { $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; $sql.= " WHERE p.entity = ".$conf->entity; } + else return 'BadValueForParameterMode'; + if ($filteronprojuser) { // TODO @@ -603,7 +607,7 @@ class Task extends CommonObject if ($projectid) $sql.= " AND p.rowid in (".$projectid.")"; if ($filteronprojref) $sql.= " AND p.ref LIKE '%".$filteronprojref."%'"; if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut = ".$filteronprojstatus; - if ($morewherefilter) $sql.=" AND (".$morewherefilter.")"; + if ($morewherefilter) $sql.=$morewherefilter; $sql.= " ORDER BY p.ref, t.rang, t.dateo"; //print $sql;exit; @@ -948,7 +952,7 @@ class Task extends CommonObject $sql.=" AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)"; } //print $sql; - + dol_syslog(get_class($this)."::getSumOfAmount", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) @@ -957,7 +961,7 @@ class Task extends CommonObject $result['amount'] = $obj->amount; $result['nblinesnull'] = $obj->nblinesnull; - + $this->db->free($resql); return $result; } diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index 4894aed413b..264afb449f9 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -51,7 +51,7 @@ $sortorder = GETPOST("sortorder",'alpha'); $socstatic=new Societe($db); $projectstatic=new Project($db); $userstatic=new User($db); -$tasktmp=new Task($db); +$form=new Form($db); $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,($mine?$mine:(empty($user->rights->projet->all->lire)?0:2)),1); //var_dump($projectsListId); @@ -73,6 +73,28 @@ else } +// Get list of ponderated percent for each status +$listofoppstatus=array(); $listofopplabel=array(); $listofoppcode=array(); +$sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label"; +$sql.= " FROM ".MAIN_DB_PREFIX."c_lead_status as cls"; +$resql = $db->query($sql); +if ( $resql ) +{ + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $listofoppstatus[$objp->rowid]=$objp->percent; + $listofopplabel[$objp->rowid]=$objp->label; + $listofoppcode[$objp->rowid]=$objp->code; + $i++; + } +} +else dol_print_error($db); + + print '
'; @@ -94,8 +116,92 @@ if (! empty($conf->projet->enabled) && $user->rights->projet->lire) print "
\n"; } + +/* + * Statistics + */ + +if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) +{ + $sql = "SELECT count(p.rowid), p.fk_opp_status as status"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " WHERE p.entity = ".$conf->entity; + $sql.= " AND p.fk_statut = 1"; + if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")"; + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + $sql.= " GROUP BY p.fk_opp_status"; + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + $total=0; + $totalinprocess=0; + $dataseries=array(); + $vals=array(); + // -1=Canceled, 0=Draft, 1=Validated, (2=Accepted/On process not managed for customer orders), 3=Closed (Sent/Received, billed or not) + while ($i < $num) + { + $row = $db->fetch_row($resql); + if ($row) + { + //if ($row[1]!=-1 && ($row[1]!=3 || $row[2]!=1)) + { + $vals[$row[1]]=$row[0]; + $totalinprocess+=$row[0]; + } + $total+=$row[0]; + } + $i++; + } + $db->free($resql); + + print ''; + print ''."\n"; + $var=true; + $listofstatus=array_keys($listofoppstatus); + foreach ($listofstatus as $status) + { + $labelstatus = ''; + + $code = dol_getIdFromCode($db, $status, 'c_lead_status', 'rowid', 'code'); + if ($code) $labelstatus = $langs->trans("OppStatus".$code); + if (empty($labelstatus)) $labelstatus=$listofopplabel[$status]; + + $labelstatus .= ' ('.$langs->trans("Coeff").': '.$listofoppstatus[$status].')'; + + $dataseries[]=array('label'=>$labelstatus,'data'=>(isset($vals[$status])?(int) $vals[$status]:0)); + if (! $conf->use_javascript_ajax) + { + $var=!$var; + print ""; + print ''; + print ''; + print "\n"; + } + } + if ($conf->use_javascript_ajax) + { + print ''; + } + //if ($totalinprocess != $total) + //print ''; + print ''; + print "
'.$langs->trans("Statistics").' - '.$langs->trans("OpportunitiesStatusForOpenedProjects").'
'.$labelstatus.''.(isset($vals[$status])?$vals[$status]:0).'
'; + $data=array('series'=>$dataseries); + dol_print_graph('stats',400,180,$data,1,'pie',1); + print '
'.$langs->trans("Total").' ('.$langs->trans("CustomersOrdersRunning").')'.$totalinprocess.'
'.$langs->trans("Total").''.$total.'

"; + } + else + { + dol_print_error($db); + } +} + + // List of draft projects -print_projecttasks_array($db,$socid,$projectsListId,0,0); +print_projecttasks_array($db,$form,$socid,$projectsListId,0,0,$listofoppstatus); print '
'; @@ -103,15 +209,16 @@ print '
'; print ''; print ''; -print_liste_field_titre($langs->trans("ThirdParties"),$_SERVER["PHP_SELF"],"s.nom","","","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("OpenedProjectsByThirdparties"),$_SERVER["PHP_SELF"],"s.nom","","","",$sortfield,$sortorder); print_liste_field_titre($langs->trans("NbOfProjects"),"","","","",'align="right"',$sortfield,$sortorder); print "\n"; -$sql = "SELECT count(p.rowid) as nb"; +$sql = "SELECT COUNT(p.rowid) as nb, SUM(p.opp_amount)"; $sql.= ", s.nom as name, s.rowid as socid"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; $sql.= " WHERE p.entity = ".$conf->entity; +$sql.= " AND p.fk_statut = 1"; if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")"; if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; $sql.= " GROUP BY s.nom, s.rowid"; @@ -140,7 +247,7 @@ if ( $resql ) print $langs->trans("OthersNotLinkedToThirdParty"); } print ''; - print ''; + print ''; print "\n"; $i++; @@ -155,143 +262,16 @@ else print "
'.$obj->nb.''.$obj->nb.'
"; +print '
'; + + +print_projecttasks_array($db,$form,$socid,$projectsListId,0,1,$listofoppstatus); + + + print '
'; -if (empty($conf->global->PROJECT_HIDE_TASKS)) -{ - // Tasks for all resources of all opened projects and time spent for each task/resource - print '
'; - - $max = (empty($conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA)?1000:$conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA); - - $sql = "SELECT p.ref, p.title, p.rowid as projectid, p.fk_statut as status, p.fk_opp_status as opp_status, t.label, t.rowid as taskid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee, SUM(tasktime.task_duration) as timespent"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tasktime on tasktime.fk_task = t.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on tasktime.fk_user = u.rowid"; - $sql.= " WHERE p.entity = ".$conf->entity; - if ($mine || empty($user->rights->projet->all->lire)) $sql.= " AND p.rowid IN (".$projectsListId.")"; - if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; - $sql.= " AND p.fk_statut=1"; - $sql.= " GROUP BY p.ref, p.title, p.rowid, t.label, t.rowid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee"; - $sql.= " ORDER BY t.dateo desc, t.rowid desc, t.datee"; - $sql.= $db->plimit($max+1); // We want more to know if we have more than limit - - $var=true; - - dol_syslog('projet:index.php: affectationpercent', LOG_DEBUG); - $resql = $db->query($sql); - if ( $resql ) - { - $num = $db->num_rows($resql); - $i = 0; - - print '
'; - - print_fiche_titre($langs->trans("TasksOnOpenedProject"),'','').'
'; - - print ''; - print ''; - //print ''; - print ''; - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - while ($i < $num && $i < $max) - { - $obj = $db->fetch_object($resql); - $var=!$var; - - $username=''; - if ($obj->userid && $userstatic->id != $obj->userid) // We have a user and it is not last loaded user - { - $result=$userstatic->fetch($obj->userid); - if (! $result) $userstatic->id=0; - } - if ($userstatic->id) $username = $userstatic->getNomUrl(0,0); - - print ""; - //print ''; - print ''; - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - $i++; - } - - if ($num > $max) - { - $colspan=6; - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) $colspan++; - print ''; - } - - print "
'.$langs->trans('TaskRessourceLinks').''.$langs->trans('Projects').''.$langs->trans('OpportunityStatus').''.$langs->trans('Task').''.$langs->trans('DateStart').''.$langs->trans('DateEnd').''.$langs->trans('PlannedWorkload').''.$langs->trans("ProgressDeclared").''; - print ''.$langs->trans('TimeSpent').''.$langs->trans("ProgressCalculated").''; - print '
'.$username.''; - $projectstatic->id=$obj->projectid; - $projectstatic->ref=$obj->ref; - $projectstatic->title=$obj->title; - print $projectstatic->getNomUrl(1,'',16); - //print ''.$obj->title.''; - print ''; - $code = dol_getIdFromCode($db, $obj->opp_status, 'c_lead_status', 'rowid', 'code'); - if ($code) print $langs->trans("OppStatus".$code); - print ''; - if (! empty($obj->taskid)) - { - $tasktmp->id = $obj->taskid; - $tasktmp->ref = $obj->label; - print $tasktmp->getNomUrl(1,'withproject'); - } - else print $langs->trans("NoTasks"); - print ''.dol_print_date($db->jdate($obj->dateo),'day').''.dol_print_date($db->jdate($obj->datee),'day').''; - print convertSecondToTime($obj->planned_workload, 'all'); - print ''; - print ($obj->taskid>0)?$obj->progress.'%':''; - print ''; - print convertSecondToTime($obj->timespent, 'all'); - print ''; - if (! empty($obj->taskid)) - { - if (empty($obj->planned_workload) > 0) { - $percentcompletion = $langs->trans("WorkloadNotDefined"); - } else { - $percentcompletion = intval($obj->duration_effective*100/$obj->planned_workload).'%'; - } - } - print $percentcompletion; - print '
'.$langs->trans("WarningTooManyDataPleaseUseMoreFilters").'
"; - - - $db->free($resql); - } - else - { - dol_print_error($db); - } - - print '
'; -} - - llxFooter(); $db->close(); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index abe0a5858fc..cb70773dcd8 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -242,16 +242,19 @@ if ($resql) if ($user->rights->societe->client->voir || $socid) { $langs->load("commercial"); + $moreforfilter.='
'; $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; - $moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user); - $moreforfilter.='       '; + $moreforfilter.=$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, 1, 'maxwidth300'); + $moreforfilter.='
'; } // If the user can view prospects other than his' if (($user->rights->societe->client->voir || $socid) && !$mine) { - $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; - $moreforfilter.=$form->select_dolusers($search_user,'search_user',1); + $moreforfilter.='
'; + $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; + $moreforfilter.=$form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + $moreforfilter.='
'; } if (! empty($moreforfilter)) { @@ -274,12 +277,10 @@ if ($resql) if (! empty($conf->global->PROJECT_LIST_SHOW_STARTDATE)) print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"p.dateo","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Visibility"),$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); - $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) print_liste_field_titre($langs->trans("OpportunityStatus"),$_SERVER["PHP_SELF"],'p.fk_opp_statut',"",$param,'',$sortfield,$sortorder); + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) print_liste_field_titre($langs->trans("OpportunityStatus"),$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],'p.fk_statut',"",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; @@ -401,6 +402,7 @@ if ($resql) $userstatic->id=$val['id']; $userstatic->lastname=$val['lastname']; $userstatic->firstname=$val['firstname']; + $userstatic->email=$val['email']; print $userstatic->getNomUrl(1); $j++; if ($j < $nbofsalesrepresentative) print ', '; diff --git a/htdocs/projet/tasks/index.php b/htdocs/projet/tasks/index.php index bc184133954..02a8eddbc59 100644 --- a/htdocs/projet/tasks/index.php +++ b/htdocs/projet/tasks/index.php @@ -41,7 +41,6 @@ $search_task_label=GETPOST('search_task_label'); $search_project_user=GETPOST('search_project_user'); $search_task_user=GETPOST('search_task_user'); - // Security check $socid=0; if ($user->societe_id > 0) $socid = $user->societe_id; @@ -63,7 +62,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both $search_task_ref=""; $search_task_label=""; } -if (empty($search_status)) $search_status=1; +if (empty($search_status) && $search_status == '') $search_status=1; /* @@ -108,8 +107,8 @@ $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$so // Get list of tasks in tasksarray and taskarrayfiltered // We need all tasks (even not limited to a user because a task assigned to a user can have a parent that is not assigned to him and we need such parents). $morewherefilter=''; -if ($search_task_ref) $morewherefilter.=natural_search('t.ref', $search_task_ref, 0, 1); -if ($search_task_label) $morewherefilter.=natural_search('t.label', $search_task_label, 0, 1); +if ($search_task_ref) $morewherefilter.=natural_search('t.ref', $search_task_ref); +if ($search_task_label) $morewherefilter.=natural_search('t.label', $search_task_label); $tasksarray=$taskstatic->getTasksArray(0, 0, $projectstatic->id, $socid, 0, $search_project, $search_status, $morewherefilter, $search_project_user, $search_task_user); // We load also tasks limited to a particular user $tasksrole=($mine ? $taskstatic->getUserRolesForProjectsOrTasks(0,$user,$projectstatic->id,0) : ''); @@ -121,22 +120,26 @@ print ''; // If the user can view users if ($user->rights->user->user->lire) { - $moreforfilter.=($moreforfilter?'   ':''); + $moreforfilter.='
'; $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ' '; - $moreforfilter.=$form->select_dolusers($search_project_user,'search_project_user',1); + $moreforfilter.=$form->select_dolusers($search_project_user, 'search_project_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + $moreforfilter.='
'; } if ($user->rights->user->user->lire) { - $moreforfilter.=($moreforfilter?'   ':''); + $moreforfilter.='
'; $moreforfilter.=$langs->trans('TasksWithThisUserAsContact'). ' '; - $moreforfilter.=$form->select_dolusers($search_task_user,'search_task_user',1); + $moreforfilter.=$form->select_dolusers($search_task_user, 'search_task_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + $moreforfilter.='
'; } if (! empty($moreforfilter)) { - print ''; - print ''; + print '
'; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; } print ''; @@ -165,10 +168,10 @@ foreach($projectstatic->statuts_short as $key => $val) $listofstatus[$key]=$lang print $form->selectarray('search_status', $listofstatus, $search_status); print ''; print ''; print ''; print '
'; - print $moreforfilter; - print '
'; -print ''; +print ''; print ''; -print ''; +print ''; print ''; print ' '; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 06b369e0141..2c7d3f25053 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1652,7 +1652,7 @@ class Societe extends CommonObject $reparray=array(); - $sql = "SELECT u.rowid, u.lastname, u.firstname"; + $sql = "SELECT u.rowid, u.lastname, u.firstname, u.email"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc, ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE u.rowid = sc.fk_user AND sc.fk_soc =".$this->id; $sql.= " AND entity in (0, ".$conf->entity.")"; @@ -1668,6 +1668,7 @@ class Societe extends CommonObject $reparray[$i]['id']=$obj->rowid; $reparray[$i]['lastname']=$obj->lastname; $reparray[$i]['firstname']=$obj->firstname; + $reparray[$i]['email']=$obj->email; $i++; } return $reparray;