2006-09-23 00:27:47 +00:00
< ? php
2015-02-02 12:27:55 +00:00
/* Copyright ( C ) 2006 - 2015 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 12:43:12 +00:00
* Copyright ( C ) 2010 Regis Houssin < regis . houssin @ inodbox . com >
2013-11-05 10:17:54 +00:00
* Copyright ( C ) 2011 Juanjo Menent < jmenent @ 2 byte . es >
2026-06-13 23:09:51 +00:00
* Copyright ( C ) 2018 - 2026 Frédéric France < frederic . france @ free . fr >
2022-06-08 11:11:28 +00:00
* Copyright ( C ) 2022 Charlene Benke < charlene @ patas - monkey . com >
2023-03-08 10:00:58 +00:00
* Copyright ( C ) 2023 Gauthier VERDOL < gauthier . verdol @ atm - consulting . fr >
2026-04-23 12:57:54 +00:00
* Copyright ( C ) 2024 - 2026 MDW < mdeweerd @ users . noreply . github . com >
2024-07-03 01:29:05 +00:00
* Copyright ( C ) 2024 Vincent de Grandpré < vincent @ de - grandpre . quebec >
2013-11-05 10:17:54 +00:00
*
* 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
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2013-11-05 10:17:54 +00:00
*/
2006-09-23 00:27:47 +00:00
/**
2022-09-18 18:50:15 +00:00
* \file htdocs / core / lib / project . lib . php
* \brief Functions used by project module
* \ingroup project
2013-11-05 10:17:54 +00:00
*/
2012-08-22 21:11:24 +00:00
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php' ;
2010-06-01 15:33:27 +00:00
2010-11-11 12:21:15 +00:00
2012-02-04 09:48:47 +00:00
/**
* Prepare array with list of tabs
*
2020-10-06 21:30:51 +00:00
* @ param Project $project Object related to tabs
2021-09-14 15:56:06 +00:00
* @ param string $moreparam More param on url
2024-09-22 22:37:30 +00:00
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
2012-02-04 09:48:47 +00:00
*/
2021-09-14 15:56:06 +00:00
function project_prepare_head ( Project $project , $moreparam = '' )
2006-09-23 00:27:47 +00:00
{
2016-01-23 16:19:34 +00:00
global $db , $langs , $conf , $user ;
2017-06-02 10:27:46 +00:00
2013-04-12 09:09:53 +00:00
$h = 0 ;
$head = array ();
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/card.php' , [ 'id' => $project -> id ]) . ( $moreparam ? '&' . $moreparam : '' );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " Project " );
$head [ $h ][ 2 ] = 'project' ;
$h ++ ;
2021-02-23 11:19:49 +00:00
$nbContacts = 0 ;
// Enable caching of project count Contacts
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
2021-02-26 22:01:18 +00:00
$cachekey = 'count_contacts_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
2013-04-12 09:09:53 +00:00
2021-02-23 11:19:49 +00:00
if ( ! is_null ( $dataretrieved )) {
$nbContacts = $dataretrieved ;
} else {
$nbContacts = count ( $project -> liste_contact ( - 1 , 'internal' )) + count ( $project -> liste_contact ( - 1 , 'external' ));
2021-02-26 22:06:33 +00:00
dol_setcache ( $cachekey , $nbContacts , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
2021-02-23 11:19:49 +00:00
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/contact.php' , [ 'id' => $project -> id ]) . ( $moreparam ? '&' . $moreparam : '' );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " ProjectContact " );
2021-02-23 11:19:49 +00:00
if ( $nbContacts > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbContacts . '</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'contact' ;
$h ++ ;
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_HIDE_TASKS' )) {
2018-12-09 23:25:10 +00:00
// Then tab for sub level of projet, i mean tasks
2021-02-23 11:19:49 +00:00
$nbTasks = 0 ;
// Enable caching of project count Tasks
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
2021-02-26 22:01:18 +00:00
$cachekey = 'count_tasks_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbTasks = $dataretrieved ;
} else {
require_once DOL_DOCUMENT_ROOT . '/projet/class/task.class.php' ;
$taskstatic = new Task ( $db );
2024-09-22 22:37:30 +00:00
$nbTasks = count ( $taskstatic -> getTasksArray ( null , null , $project -> id , 0 , 0 ));
2021-02-23 11:19:49 +00:00
dol_setcache ( $cachekey , $nbTasks , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/tasks.php' , [ 'id' => $project -> id ]) . ( $moreparam ? '&' . $moreparam : '' );
2018-12-09 23:25:10 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " Tasks " );
2021-02-23 11:19:49 +00:00
if ( $nbTasks > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . ( $nbTasks ) . '</span>' ;
}
2018-12-09 23:25:10 +00:00
$head [ $h ][ 2 ] = 'tasks' ;
$h ++ ;
2019-11-13 18:35:02 +00:00
$nbTimeSpent = 0 ;
2021-02-23 11:19:49 +00:00
// Enable caching of project count Timespent
2021-02-26 22:01:18 +00:00
$cachekey = 'count_timespent_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbTimeSpent = $dataretrieved ;
} else {
$sql = " SELECT t.rowid " ;
2023-04-07 01:08:02 +00:00
//$sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u";
2021-02-23 11:19:49 +00:00
//$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid";
2023-03-08 10:00:58 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " element_time as t, " . MAIN_DB_PREFIX . " projet_task as pt " ;
$sql .= " WHERE t.fk_element = pt.rowid " ;
$sql .= " AND t.elementtype = 'task' " ;
2021-08-23 16:56:46 +00:00
$sql .= " AND pt.fk_projet = " . (( int ) $project -> id );
2021-02-23 11:19:49 +00:00
$resql = $db -> query ( $sql );
if ( $resql ) {
$obj = $db -> fetch_object ( $resql );
if ( $obj ) {
$nbTimeSpent = 1 ;
dol_setcache ( $cachekey , $nbTimeSpent , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
} else {
dol_print_error ( $db );
}
}
2018-12-09 23:25:10 +00:00
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/tasks/time.php' , [ 'withproject' => 1 , 'projectid' => $project -> id ]) . ( $moreparam ? '&' . $moreparam : '' );
2018-12-09 23:25:10 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " TimeSpent " );
2021-02-23 11:19:49 +00:00
if ( $nbTimeSpent > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">...</span>' ;
}
2018-12-09 23:25:10 +00:00
$head [ $h ][ 2 ] = 'timespent' ;
$h ++ ;
}
2023-04-18 14:15:13 +00:00
if ( isModEnabled ( " supplier_proposal " ) || isModEnabled ( " supplier_order " ) || isModEnabled ( " supplier_invoice " )
2024-02-27 14:30:37 +00:00
|| isModEnabled ( " propal " ) || isModEnabled ( 'order' )
|| isModEnabled ( 'invoice' ) || isModEnabled ( 'contract' )
|| isModEnabled ( 'intervention' ) || isModEnabled ( 'agenda' ) || isModEnabled ( 'deplacement' ) || isModEnabled ( 'stock' )) {
2021-02-23 11:19:49 +00:00
$nbElements = 0 ;
// Enable caching of thirdrparty count Contacts
2021-02-26 22:01:18 +00:00
$cachekey = 'count_elements_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbElements = $dataretrieved ;
} else {
2022-09-25 04:02:37 +00:00
if ( isModEnabled ( 'stock' )) {
2021-09-21 09:22:59 +00:00
$nbElements += $project -> getElementCount ( 'stock' , 'entrepot' , 'fk_project' );
}
2022-08-23 18:01:34 +00:00
if ( isModEnabled ( " propal " )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'propal' , 'propal' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( 'order' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'order' , 'commande' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( 'invoice' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'invoice' , 'facture' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( 'invoice' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'invoice_predefined' , 'facture_rec' );
2021-02-23 11:19:49 +00:00
}
2022-08-31 20:02:31 +00:00
if ( isModEnabled ( 'supplier_proposal' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'proposal_supplier' , 'supplier_proposal' );
2021-02-23 11:19:49 +00:00
}
2022-08-23 18:05:09 +00:00
if ( isModEnabled ( " supplier_order " )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'order_supplier' , 'commande_fournisseur' );
2021-02-23 11:19:49 +00:00
}
2022-08-23 18:05:09 +00:00
if ( isModEnabled ( " supplier_invoice " )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'invoice_supplier' , 'facture_fourn' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( 'contract' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'contract' , 'contrat' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( 'intervention' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'intervention' , 'fichinter' );
2021-02-23 11:19:49 +00:00
}
2024-03-12 10:07:18 +00:00
if ( isModEnabled ( " shipping " )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'shipping' , 'expedition' );
2021-02-23 11:19:49 +00:00
}
2022-09-25 20:57:24 +00:00
if ( isModEnabled ( 'mrp' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'mrp' , 'mrp_mo' , 'fk_project' );
2021-02-23 11:19:49 +00:00
}
2022-08-31 19:55:55 +00:00
if ( isModEnabled ( 'deplacement' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'trip' , 'deplacement' );
2021-02-23 11:19:49 +00:00
}
2022-08-31 19:55:55 +00:00
if ( isModEnabled ( 'expensereport' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'expensereport' , 'expensereport' );
2021-02-23 11:19:49 +00:00
}
2022-09-25 04:18:33 +00:00
if ( isModEnabled ( 'don' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'donation' , 'don' );
2021-02-23 11:19:49 +00:00
}
2023-06-27 19:31:36 +00:00
if ( isModEnabled ( 'loan' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'loan' , 'loan' );
2021-02-23 11:19:49 +00:00
}
2022-08-31 19:55:55 +00:00
if ( isModEnabled ( 'tax' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'chargesociales' , 'chargesociales' );
2021-02-23 11:19:49 +00:00
}
2022-08-31 20:12:10 +00:00
if ( isModEnabled ( 'project' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'project_task' , 'projet_task' );
2021-02-23 11:19:49 +00:00
}
2026-04-28 09:07:19 +00:00
if ( isModEnabled ( 'stocktransfer' )) {
$nbElements += $project -> getElementCount ( 'stocktransfer' , 'stocktransfer_stocktransfer' , 'fk_project' );
}
2022-09-25 04:02:37 +00:00
if ( isModEnabled ( 'stock' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'stock_mouvement' , 'stock' );
2021-02-23 11:19:49 +00:00
}
2023-06-27 19:31:36 +00:00
if ( isModEnabled ( 'salaries' )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'salaries' , 'payment_salary' );
2021-02-23 11:19:49 +00:00
}
2024-02-27 14:30:37 +00:00
if ( isModEnabled ( " bank " )) {
2021-02-26 22:06:33 +00:00
$nbElements += $project -> getElementCount ( 'variouspayment' , 'payment_various' );
2021-02-23 11:19:49 +00:00
}
2021-02-26 22:06:33 +00:00
dol_setcache ( $cachekey , $nbElements , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
2021-02-23 11:19:49 +00:00
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/element.php' , [ 'id' => $project -> id ]);
2015-10-06 14:03:47 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " ProjectOverview " );
2021-02-23 11:19:49 +00:00
if ( $nbElements > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbElements . '</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'element' ;
$h ++ ;
}
2022-12-01 17:45:30 +00:00
if ( isModEnabled ( 'ticket' ) && $user -> hasRight ( 'ticket' , 'read' )) {
require_once DOL_DOCUMENT_ROOT . '/ticket/class/ticket.class.php' ;
$Tickettatic = new Ticket ( $db );
2023-09-01 15:26:13 +00:00
$nbTicket = $Tickettatic -> getCountOfItemsLinkedByObjectID ( $project -> id , 'fk_project' , 'ticket' );
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/ticket/list.php' , [ 'projectid' => $project -> id ]);
2022-12-01 17:45:30 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " Ticket " );
if ( $nbTicket > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . ( $nbTicket ) . '</span>' ;
}
$head [ $h ][ 2 ] = 'ticket' ;
$h ++ ;
}
2022-08-31 20:38:53 +00:00
if ( isModEnabled ( 'eventorganization' ) && ! empty ( $project -> usage_organize_event )) {
2021-02-20 22:17:48 +00:00
$langs -> load ( 'eventorganization' );
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/eventorganization/conferenceorbooth_list.php' , [ 'projectid' => $project -> id ]);
2021-09-08 00:27:52 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " EventOrganization " );
2021-03-24 19:13:30 +00:00
// Enable caching of conf or booth count
2023-12-04 11:05:28 +00:00
$nbConfOrBooth = 0 ;
$nbAttendees = 0 ;
2021-03-24 19:13:30 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
$cachekey = 'count_conferenceorbooth_' . $project -> id ;
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbConfOrBooth = $dataretrieved ;
} else {
require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorbooth.class.php' ;
2024-03-12 23:30:00 +00:00
$conforbooth = new ConferenceOrBooth ( $db );
2024-03-05 02:51:36 +00:00
$result = $conforbooth -> fetchAll ( '' , '' , 0 , 0 , '(t.fk_project:=:' . (( int ) $project -> id ) . " ) " );
2021-03-24 19:13:30 +00:00
//,
2024-03-12 23:30:00 +00:00
if ( ! is_array ( $result ) && $result < 0 ) {
2021-03-24 19:13:30 +00:00
setEventMessages ( $conforbooth -> error , $conforbooth -> errors , 'errors' );
} else {
$nbConfOrBooth = count ( $result );
}
dol_setcache ( $cachekey , $nbConfOrBooth , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
2023-05-04 19:41:59 +00:00
$cachekey = 'count_attendees_' . $project -> id ;
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbAttendees = $dataretrieved ;
} else {
require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorboothattendee.class.php' ;
2024-03-12 23:30:00 +00:00
$conforboothattendee = new ConferenceOrBoothAttendee ( $db );
2024-03-05 02:51:36 +00:00
$result = $conforboothattendee -> fetchAll ( '' , '' , 0 , 0 , '(t.fk_project:=:' . (( int ) $project -> id ) . ')' );
2024-03-12 23:30:00 +00:00
if ( ! is_array ( $result ) && $result < 0 ) {
2023-05-04 19:41:59 +00:00
setEventMessages ( $conforboothattendee -> error , $conforboothattendee -> errors , 'errors' );
} else {
$nbAttendees = count ( $result );
}
dol_setcache ( $cachekey , $nbAttendees , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
if ( $nbConfOrBooth > 0 || $nbAttendees > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' ;
$head [ $h ][ 1 ] .= '<span title="' . dol_escape_htmltag ( $langs -> trans ( " ConferenceOrBooth " )) . '">' . $nbConfOrBooth . '</span>' ;
2024-03-19 21:18:23 +00:00
$head [ $h ][ 1 ] .= ' + ' ;
2023-05-04 19:41:59 +00:00
$head [ $h ][ 1 ] .= '<span title="' . dol_escape_htmltag ( $langs -> trans ( " Attendees " )) . '">' . $nbAttendees . '</span>' ;
$head [ $h ][ 1 ] .= '</span>' ;
2021-02-23 21:03:23 +00:00
}
2021-02-20 22:17:48 +00:00
$head [ $h ][ 2 ] = 'eventorganisation' ;
$h ++ ;
}
2026-04-07 03:09:02 +00:00
if ( isModEnabled ( 'mailing' ) && getDolGlobalInt ( 'MAILING_ADD_TAB_ON_PROJECT' )) { // Show this tab only in hidden option is on (we can already get the information from other view and we mustfight againstthe tabflation).
$langs -> load ( 'mails' );
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/comm/mailing/list.php' , [ 'projectid' => $project -> id ]);
$head [ $h ][ 1 ] = $langs -> trans ( " EMailings " );
// Enable caching of mass mailing count
$nbMassMailing = 0 ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
$cachekey = 'count_mass_mailing_' . $project -> id ;
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbMassMailing = $dataretrieved ;
} else {
require_once DOL_DOCUMENT_ROOT . '/comm/mailing/class/mailing.class.php' ;
$massMailing = new Mailing ( $db );
$result = $massMailing -> fetchAll ( '' , '' , 0 , 0 , '(t.fk_project:=:' . (( int ) $project -> id ) . " ) " );
//,
if ( ! is_array ( $result ) && $result < 0 ) {
setEventMessages ( $massMailing -> error , $massMailing -> errors , 'errors' );
} else {
$nbMassMailing = count ( $result );
}
dol_setcache ( $cachekey , $nbMassMailing , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
if ( $nbMassMailing > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' ;
$head [ $h ][ 1 ] .= '<span title="' . dol_escape_htmltag ( $langs -> trans ( " EMailings " )) . '">' . $nbMassMailing . '</span>' ;
$head [ $h ][ 1 ] .= '</span>' ;
}
$head [ $h ][ 2 ] = 'mailing' ;
$h ++ ;
}
2013-04-12 09:09:53 +00:00
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
2022-09-22 12:06:50 +00:00
complete_head_from_modules ( $conf , $langs , $project , $head , $h , 'project' , 'add' , 'core' );
2017-10-04 11:17:16 +00:00
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'MAIN_DISABLE_NOTES_TAB' )) {
2017-10-07 11:09:31 +00:00
$nbNote = 0 ;
2021-02-23 11:19:49 +00:00
if ( ! empty ( $project -> note_private )) {
$nbNote ++ ;
}
if ( ! empty ( $project -> note_public )) {
$nbNote ++ ;
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/note.php' , [ 'id' => $project -> id ]);
2013-07-20 08:54:38 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( 'Notes' );
2021-02-23 11:19:49 +00:00
if ( $nbNote > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbNote . '</span>' ;
}
2013-07-20 08:54:38 +00:00
$head [ $h ][ 2 ] = 'notes' ;
$h ++ ;
2017-10-07 11:09:31 +00:00
}
2013-10-30 10:57:32 +00:00
2021-02-23 11:19:49 +00:00
// Attached files and Links
$totalAttached = 0 ;
// Enable caching of thirdrparty count attached files and links
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
2021-02-26 22:01:18 +00:00
$cachekey = 'count_attached_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$totalAttached = $dataretrieved ;
} else {
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php' ;
2023-10-20 10:44:08 +00:00
$upload_dir = $conf -> project -> multidir_output [ empty ( $project -> entity ) ? 1 : $project -> entity ] . " / " . dol_sanitizeFileName ( $project -> ref );
2021-02-23 11:19:49 +00:00
$nbFiles = count ( dol_dir_list ( $upload_dir , 'files' , 0 , '' , '(\.meta|_preview.*\.png)$' ));
$nbLinks = Link :: count ( $db , $project -> element , $project -> id );
$totalAttached = $nbFiles + $nbLinks ;
dol_setcache ( $cachekey , $totalAttached , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/document.php' , [ 'id' => $project -> id ]);
2013-04-12 09:09:53 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( 'Documents' );
2021-02-23 11:19:49 +00:00
if (( $totalAttached ) > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . ( $totalAttached ) . '</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'document' ;
$h ++ ;
2013-10-30 10:57:32 +00:00
2017-10-04 11:17:16 +00:00
// Manage discussion
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_ALLOW_COMMENT_ON_PROJECT' )) {
2021-02-23 11:19:49 +00:00
$nbComments = 0 ;
// Enable caching of thirdrparty count attached files and links
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
2021-02-26 22:01:18 +00:00
$cachekey = 'count_attached_project_' . $project -> id ;
2021-02-23 11:19:49 +00:00
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbComments = $dataretrieved ;
} else {
$nbComments = $project -> getNbComments ();
dol_setcache ( $cachekey , $nbComments , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/comment.php' , [ 'id' => $project -> id ]);
2017-10-04 11:17:16 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " CommentLink " );
2021-02-23 11:19:49 +00:00
if ( $nbComments > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbComments . '</span>' ;
}
2017-10-04 11:17:16 +00:00
$head [ $h ][ 2 ] = 'project_comment' ;
$h ++ ;
}
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/projet/messaging.php' , [ 'id' => $project -> id ]);
2021-10-24 07:33:54 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " Events " );
2023-06-12 18:10:42 +00:00
if ( isModEnabled ( 'agenda' ) && ( $user -> hasRight ( 'agenda' , 'myactions' , 'read' ) || $user -> hasRight ( 'agenda' , 'allactions' , 'read' ))) {
2026-01-25 14:55:05 +00:00
$nbEvent = 0 ;
// Enable caching of project count actioncomm
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
$cachekey = 'count_events_project_' . $project -> id ;
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$nbEvent = $dataretrieved ;
} else {
$sql = " SELECT COUNT(id) as nb " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " actioncomm " ;
$sql .= " WHERE fk_project = " . (( int ) $project -> id );
$resql = $db -> query ( $sql );
if ( $resql ) {
$obj = $db -> fetch_object ( $resql );
$nbEvent = $obj -> nb ;
} else {
dol_syslog ( 'Failed to count actioncomm ' . $db -> lasterror (), LOG_ERR );
}
dol_setcache ( $cachekey , $nbEvent , 120 ); // If setting cache fails, this is not a problem, so we do not test result.
}
2019-11-13 18:35:02 +00:00
$head [ $h ][ 1 ] .= '/' ;
$head [ $h ][ 1 ] .= $langs -> trans ( " Agenda " );
2026-01-25 14:55:05 +00:00
if ( $nbEvent > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbEvent . '</span>' ;
}
2017-10-07 11:09:31 +00:00
}
2016-10-17 15:52:58 +00:00
$head [ $h ][ 2 ] = 'agenda' ;
2016-07-09 13:30:42 +00:00
$h ++ ;
2017-06-02 10:27:46 +00:00
2022-09-22 12:06:50 +00:00
complete_head_from_modules ( $conf , $langs , $project , $head , $h , 'project' , 'add' , 'external' );
2020-10-06 10:56:28 +00:00
complete_head_from_modules ( $conf , $langs , $project , $head , $h , 'project' , 'remove' );
2013-04-12 09:09:53 +00:00
return $head ;
2006-09-23 00:27:47 +00:00
}
2008-01-11 10:25:26 +00:00
/**
2012-02-04 09:48:47 +00:00
* Prepare array with list of tabs
*
2024-09-22 22:37:30 +00:00
* @ param CommonObject $object Object related to tabs
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
2009-01-14 23:36:51 +00:00
*/
function task_prepare_head ( $object )
{
2026-05-12 00:53:35 +00:00
global $db , $langs , $conf ;
2013-04-12 09:09:53 +00:00
$h = 0 ;
$head = array ();
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/task.php?id=' . $object -> id . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2020-09-09 11:57:35 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " Task " );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'task_task' ;
$h ++ ;
2019-01-27 10:55:16 +00:00
$nbContact = count ( $object -> liste_contact ( - 1 , 'internal' )) + count ( $object -> liste_contact ( - 1 , 'external' ));
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/contact.php?id=' . $object -> id . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " TaskRessourceLinks " );
2021-02-23 21:03:23 +00:00
if ( $nbContact > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbContact . '</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'task_contact' ;
$h ++ ;
2017-04-11 00:48:16 +00:00
// Is there timespent ?
2019-11-13 18:35:02 +00:00
$nbTimeSpent = 0 ;
2017-04-11 00:48:16 +00:00
$sql = " SELECT t.rowid " ;
2023-04-07 01:08:02 +00:00
//$sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u";
2018-08-21 12:52:22 +00:00
//$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid";
2023-03-08 10:00:58 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " element_time as t " ;
$sql .= " WHERE t.elementtype='task' AND t.fk_element = " . (( int ) $object -> id );
2017-04-11 00:48:16 +00:00
$resql = $db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2017-10-07 11:09:31 +00:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $obj ) {
$nbTimeSpent = 1 ;
}
} else {
dol_print_error ( $db );
}
2017-06-02 10:27:46 +00:00
2024-09-22 22:37:30 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/time.php?id=' . urlencode (( string ) $object -> id ) . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " TimeSpent " );
2021-02-23 21:03:23 +00:00
if ( $nbTimeSpent > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">...</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'task_time' ;
$h ++ ;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
2022-09-22 12:06:50 +00:00
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'task' , 'add' , 'core' );
2017-09-18 11:15:24 +00:00
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'MAIN_DISABLE_NOTES_TAB' )) {
2017-10-07 11:09:31 +00:00
$nbNote = 0 ;
2021-02-23 21:03:23 +00:00
if ( ! empty ( $object -> note_private )) {
$nbNote ++ ;
}
if ( ! empty ( $object -> note_public )) {
$nbNote ++ ;
}
2024-09-22 22:37:30 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/note.php?id=' . urlencode (( string ) $object -> id ) . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2014-05-10 14:43:47 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( 'Notes' );
2021-02-23 21:03:23 +00:00
if ( $nbNote > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbNote . '</span>' ;
}
2014-05-10 14:43:47 +00:00
$head [ $h ][ 2 ] = 'task_notes' ;
$h ++ ;
2017-10-07 11:09:31 +00:00
}
2017-09-18 11:15:24 +00:00
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/document.php?id=' . $object -> id . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2025-09-07 23:48:52 +00:00
$filesdir = $conf -> project -> multidir_output [ $object -> entity ? ? $conf -> entity ] . " / " . dol_sanitizeFileName ( $object -> project -> ref ) . '/' . dol_sanitizeFileName ( $object -> ref );
2014-05-10 14:43:47 +00:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2016-06-16 12:08:14 +00:00
include_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php' ;
2019-01-27 10:55:16 +00:00
$nbFiles = count ( dol_dir_list ( $filesdir , 'files' , 0 , '' , '(\.meta|_preview.*\.png)$' ));
2019-11-13 18:35:02 +00:00
$nbLinks = Link :: count ( $db , $object -> element , $object -> id );
2016-03-29 18:06:01 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( 'Documents' );
2021-02-23 21:03:23 +00:00
if (( $nbFiles + $nbLinks ) > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . ( $nbFiles + $nbLinks ) . '</span>' ;
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'task_document' ;
$h ++ ;
2017-10-04 11:17:16 +00:00
// Manage discussion
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_ALLOW_COMMENT_ON_TASK' )) {
2017-10-04 11:17:16 +00:00
$nbComments = $object -> getNbComments ();
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/tasks/comment.php?id=' . $object -> id . ( GETPOST ( 'withproject' ) ? '&withproject=1' : '' );
2017-10-04 11:17:16 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " CommentLink " );
2021-02-23 21:03:23 +00:00
if ( $nbComments > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbComments . '</span>' ;
}
2017-10-04 11:17:16 +00:00
$head [ $h ][ 2 ] = 'task_comment' ;
$h ++ ;
}
2022-09-22 12:06:50 +00:00
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'task' , 'add' , 'external' );
2019-01-27 10:55:16 +00:00
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'task' , 'remove' );
2013-04-12 09:09:53 +00:00
return $head ;
}
2015-03-01 16:45:36 +00:00
/**
* Prepare array with list of tabs
*
* @ param string $mode Mode
2024-11-04 22:53:20 +00:00
* @ param User | string $fuser Filter on user
2024-09-22 22:37:30 +00:00
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
2015-03-01 16:45:36 +00:00
*/
2019-01-27 14:20:16 +00:00
function project_timesheet_prepare_head ( $mode , $fuser = null )
2015-03-01 16:45:36 +00:00
{
global $langs , $conf , $user ;
$h = 0 ;
$head = array ();
2019-11-13 18:35:02 +00:00
$param = '' ;
$param .= ( $mode ? '&mode=' . $mode : '' );
2021-02-23 21:03:23 +00:00
if ( is_object ( $fuser ) && $fuser -> id > 0 && $fuser -> id != $user -> id ) {
$param .= '&search_usertoprocessid=' . $fuser -> id ;
}
2017-06-02 10:27:46 +00:00
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_DISABLE_TIMESHEET_PERMONTH' )) {
2020-02-21 16:53:37 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . " /projet/activity/permonth.php " . ( $param ? '?' . $param : '' );
2019-11-21 16:05:06 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " InputPerMonth " );
$head [ $h ][ 2 ] = 'inputpermonth' ;
$h ++ ;
}
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_DISABLE_TIMESHEET_PERWEEK' )) {
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . " /projet/activity/perweek.php " . ( $param ? '?' . $param : '' );
2015-03-18 10:04:50 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " InputPerWeek " );
$head [ $h ][ 2 ] = 'inputperweek' ;
$h ++ ;
}
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_DISABLE_TIMESHEET_PERTIME' )) {
2019-11-13 18:35:02 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . " /projet/activity/perday.php " . ( $param ? '?' . $param : '' );
2015-03-05 12:48:57 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " InputPerDay " );
$head [ $h ][ 2 ] = 'inputperday' ;
$h ++ ;
}
2015-03-01 16:45:36 +00:00
2019-01-27 10:55:16 +00:00
complete_head_from_modules ( $conf , $langs , null , $head , $h , 'project_timesheet' );
2015-03-01 16:45:36 +00:00
2019-01-27 10:55:16 +00:00
complete_head_from_modules ( $conf , $langs , null , $head , $h , 'project_timesheet' , 'remove' );
2015-03-01 16:45:36 +00:00
return $head ;
}
2013-04-12 09:09:53 +00:00
/**
* Prepare array with list of tabs
*
2024-09-22 22:37:30 +00:00
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
2013-04-12 09:09:53 +00:00
*/
function project_admin_prepare_head ()
{
2026-06-13 23:09:51 +00:00
global $langs , $conf , $user , $extrafields ;
2022-09-18 18:50:15 +00:00
$extrafields -> fetch_name_optionals_label ( 'projet' );
$extrafields -> fetch_name_optionals_label ( 'projet_task' );
2013-04-12 09:09:53 +00:00
$h = 0 ;
2022-09-18 18:50:15 +00:00
$head = array ();
2013-04-12 09:09:53 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . " /projet/admin/project.php " ;
$head [ $h ][ 1 ] = $langs -> trans ( " Projects " );
$head [ $h ][ 2 ] = 'project' ;
$h ++ ;
2019-01-27 10:55:16 +00:00
complete_head_from_modules ( $conf , $langs , null , $head , $h , 'project_admin' );
2013-04-12 09:09:53 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . " /projet/admin/project_extrafields.php " ;
$head [ $h ][ 1 ] = $langs -> trans ( " ExtraFieldsProject " );
2022-09-18 18:50:15 +00:00
$nbExtrafields = $extrafields -> attributes [ 'projet' ][ 'count' ];
if ( $nbExtrafields > 0 ) {
2022-09-22 12:42:58 +00:00
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbExtrafields . '</span>' ;
2022-09-18 18:50:15 +00:00
}
2013-04-12 09:09:53 +00:00
$head [ $h ][ 2 ] = 'attributes' ;
$h ++ ;
2025-09-18 14:26:38 +00:00
if ( ! getDolGlobalString ( 'PROJECT_HIDE_TASKS' )) {
2024-05-01 15:37:12 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/admin/project_task_extrafields.php' ;
$head [ $h ][ 1 ] = $langs -> trans ( " ExtraFieldsProjectTask " );
$nbExtrafields = $extrafields -> attributes [ 'projet_task' ][ 'count' ];
if ( $nbExtrafields > 0 ) {
$head [ $h ][ 1 ] .= '<span class="badge marginleftonlyshort">' . $nbExtrafields . '</span>' ;
}
$head [ $h ][ 2 ] = 'attributes_task' ;
$h ++ ;
2022-09-18 18:50:15 +00:00
}
2013-04-12 09:09:53 +00:00
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_USE_OPPORTUNITIES' )) {
2022-05-16 11:57:11 +00:00
$langs -> load ( " members " );
2021-02-24 11:19:28 +00:00
2022-05-16 11:57:11 +00:00
$head [ $h ][ 0 ] = DOL_URL_ROOT . '/projet/admin/website.php' ;
$head [ $h ][ 1 ] = $langs -> trans ( " BlankSubscriptionForm " );
$head [ $h ][ 2 ] = 'website' ;
$h ++ ;
}
2021-02-24 11:19:28 +00:00
2019-01-27 10:55:16 +00:00
complete_head_from_modules ( $conf , $langs , null , $head , $h , 'project_admin' , 'remove' );
2013-04-12 09:09:53 +00:00
return $head ;
2009-01-14 23:36:51 +00:00
}
/**
2009-07-28 00:52:34 +00:00
* Show task lines with a particular parent
2011-12-04 14:26:32 +00:00
*
2024-11-21 21:36:00 +00:00
* @ param int $inc Line number ( start to 0 , then increased by recursive call )
2024-09-05 14:05:37 +00:00
* @ param int $parent Id of parent task to show ( 0 to show all )
2019-03-29 13:34:55 +00:00
* @ param Task [] $lines Array of lines
* @ param int $level Level ( start to 0 , then increased / decrease by recursive call ), or - 1 to show all level in order of $lines without the recursive groupment feature .
2024-09-26 00:48:16 +00:00
* @ param string $var Not used
2019-03-29 13:34:55 +00:00
* @ param int $showproject Show project columns
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $taskrole Array of roles of user for each tasks
2024-09-26 00:48:16 +00:00
* @ param string $projectsListId List of id of projects allowed to user ( string separated with comma )
2019-03-29 13:34:55 +00:00
* @ param int $addordertick Add a tick to move task
* @ param int $projectidfortotallink 0 or Id of project to use on total line ( link to see all time consumed for project )
2023-06-29 13:54:09 +00:00
* @ param string $dummy Not used .
2024-01-07 20:49:17 +00:00
* @ param int $showbilltime Add the column 'TimeToBill' and 'TimeBilled'
2025-01-27 13:00:59 +00:00
* @ param array < string , array < string , int | string >> $arrayfields Array with displayed column information
2024-09-22 22:37:30 +00:00
* @ param string [] $arrayofselected Array with selected fields
2019-09-01 19:31:07 +00:00
* @ return int Nb of tasks shown
2009-01-14 23:36:51 +00:00
*/
2023-06-29 13:54:09 +00:00
function projectLinesa ( & $inc , $parent , & $lines , & $level , $var , $showproject , & $taskrole , $projectsListId = '' , $addordertick = 0 , $projectidfortotallink = 0 , $dummy = '' , $showbilltime = 0 , $arrayfields = array (), $arrayofselected = array ())
2009-01-14 23:36:51 +00:00
{
2020-03-24 18:50:01 +00:00
global $user , $langs , $conf , $db , $hookmanager ;
2020-03-26 07:24:20 +00:00
global $projectstatic , $taskstatic , $extrafields ;
2025-08-22 03:18:25 +00:00
global $objectoffield ;
2012-02-04 13:39:47 +00:00
2024-09-22 22:37:30 +00:00
'
@ phan - var - force Project $projectstatic
@ phan - var - force Task $taskstatic
@ phan - var - force ExtraFields $extrafields
' ;
2019-11-13 18:35:02 +00:00
$lastprojectid = 0 ;
2013-04-12 09:09:53 +00:00
2024-09-26 00:48:16 +00:00
$projectsArrayId = array ();
if ( $projectsListId ) {
$projectsArrayId = explode ( ',' , $projectsListId );
}
2023-06-29 13:54:09 +00:00
2019-11-13 18:35:02 +00:00
$numlines = count ( $lines );
2013-04-12 09:09:53 +00:00
2014-03-17 14:13:24 +00:00
// We declare counter as global because we want to edit them into recursive call
2021-10-15 08:24:56 +00:00
global $total_projectlinesa_spent , $total_projectlinesa_planned , $total_projectlinesa_spent_if_planned , $total_projectlinesa_declared_if_planned , $total_projectlinesa_tobill , $total_projectlinesa_billed , $total_budget_amount ;
2023-06-04 16:54:38 +00:00
global $totalarray ;
2019-07-25 15:54:14 +00:00
2021-02-23 21:03:23 +00:00
if ( $level == 0 ) {
2019-11-13 18:35:02 +00:00
$total_projectlinesa_spent = 0 ;
$total_projectlinesa_planned = 0 ;
$total_projectlinesa_spent_if_planned = 0 ;
2020-10-31 13:32:18 +00:00
$total_projectlinesa_declared_if_planned = 0 ;
2019-11-13 18:35:02 +00:00
$total_projectlinesa_tobill = 0 ;
$total_projectlinesa_billed = 0 ;
2021-10-15 08:24:56 +00:00
$total_budget_amount = 0 ;
2023-06-04 16:54:38 +00:00
$totalarray = array ();
2014-03-17 14:13:24 +00:00
}
2013-04-12 09:09:53 +00:00
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $parent == 0 && $level >= 0 ) {
2024-01-13 18:48:20 +00:00
$level = 0 ; // if $level = -1, we don't use sublevel recursion, we show all lines
2021-02-23 21:03:23 +00:00
}
2013-04-12 09:09:53 +00:00
// Process line
// print "i:".$i."-".$lines[$i]->fk_project.'<br>';
2024-01-13 18:48:20 +00:00
if ( $lines [ $i ] -> fk_task_parent == $parent || $level < 0 ) { // if $level = -1, we don't use sublevel recursion, we show all lines
2013-04-12 09:09:53 +00:00
// Show task line.
2019-11-13 18:35:02 +00:00
$showline = 1 ;
$showlineingray = 0 ;
2013-04-12 09:09:53 +00:00
// If there is filters to use
2021-02-23 21:03:23 +00:00
if ( is_array ( $taskrole )) {
2013-04-12 09:09:53 +00:00
// If task not legitimate to show, search if a legitimate task exists later in tree
2023-06-29 14:30:34 +00:00
if ( ! isset ( $taskrole [ $lines [ $i ] -> id ]) && $lines [ $i ] -> id != $lines [ $i ] -> fk_task_parent ) {
2013-04-12 09:09:53 +00:00
// So search if task has a subtask legitimate to show
2019-11-13 18:35:02 +00:00
$foundtaskforuserdeeper = 0 ;
2019-01-27 10:55:16 +00:00
searchTaskInChild ( $foundtaskforuserdeeper , $lines [ $i ] -> id , $lines , $taskrole );
2013-04-12 09:09:53 +00:00
//print '$foundtaskforuserpeeper='.$foundtaskforuserdeeper.'<br>';
2021-02-23 21:03:23 +00:00
if ( $foundtaskforuserdeeper > 0 ) {
2019-11-13 18:35:02 +00:00
$showlineingray = 1 ; // We will show line but in gray
2020-05-21 13:05:19 +00:00
} else {
2019-11-13 18:35:02 +00:00
$showline = 0 ; // No reason to show line
2013-04-12 09:09:53 +00:00
}
}
2020-05-21 13:05:19 +00:00
} else {
2014-01-06 11:42:50 +00:00
// Caller did not ask to filter on tasks of a specific user (this probably means he want also tasks of all users, into public project
// or into all other projects if user has permission to).
2023-10-15 13:32:35 +00:00
if ( ! $user -> hasRight ( 'projet' , 'all' , 'lire' )) {
2014-01-06 11:42:50 +00:00
// User is not allowed on this project and project is not public, so we hide line
2021-02-23 21:03:23 +00:00
if ( ! in_array ( $lines [ $i ] -> fk_project , $projectsArrayId )) {
2014-01-06 12:02:20 +00:00
// Note that having a user assigned to a task into a project user has no permission on, should not be possible
2024-01-13 18:48:20 +00:00
// because assignment on task can be done only on contact of project.
// If assignment was done and after, was removed from contact of project, then we can hide the line.
2019-11-13 18:35:02 +00:00
$showline = 0 ;
2014-01-06 11:42:50 +00:00
}
}
}
2013-04-12 09:09:53 +00:00
2021-02-23 21:03:23 +00:00
if ( $showline ) {
2013-04-12 09:09:53 +00:00
// Break on a new project
2021-02-23 21:03:23 +00:00
if ( $parent == 0 && $lines [ $i ] -> fk_project != $lastprojectid ) {
2019-11-13 18:35:02 +00:00
$lastprojectid = $lines [ $i ] -> fk_project ;
2013-04-12 09:09:53 +00:00
}
2020-03-23 19:16:51 +00:00
print '<tr class="oddeven" id="row-' . $lines [ $i ] -> id . '">' . " \n " ;
2013-04-12 09:09:53 +00:00
2019-11-13 18:35:02 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
$projectstatic -> ref = $lines [ $i ] -> projectref ;
$projectstatic -> public = $lines [ $i ] -> public ;
$projectstatic -> title = $lines [ $i ] -> projectlabel ;
$projectstatic -> usage_bill_time = $lines [ $i ] -> usage_bill_time ;
2021-01-18 11:07:40 +00:00
$projectstatic -> status = $lines [ $i ] -> projectstatus ;
2019-03-29 13:34:55 +00:00
2019-11-13 18:35:02 +00:00
$taskstatic -> id = $lines [ $i ] -> id ;
$taskstatic -> ref = $lines [ $i ] -> ref ;
2022-06-08 11:11:28 +00:00
$taskstatic -> label = ( ! empty ( $taskrole [ $lines [ $i ] -> id ]) ? $langs -> trans ( " YourRole " ) . ': ' . $taskrole [ $lines [ $i ] -> id ] : '' );
2019-03-29 13:34:55 +00:00
$taskstatic -> projectstatus = $lines [ $i ] -> projectstatus ;
$taskstatic -> progress = $lines [ $i ] -> progress ;
2024-05-28 23:10:56 +00:00
$taskstatic -> fk_statut = $lines [ $i ] -> status ; // deprecated
$taskstatic -> status = $lines [ $i ] -> status ;
2020-11-28 00:14:45 +00:00
$taskstatic -> date_start = $lines [ $i ] -> date_start ;
$taskstatic -> date_end = $lines [ $i ] -> date_end ;
2020-12-01 01:41:19 +00:00
$taskstatic -> datee = $lines [ $i ] -> date_end ; // deprecated
2020-10-31 13:32:18 +00:00
$taskstatic -> planned_workload = $lines [ $i ] -> planned_workload ;
2023-06-29 13:54:09 +00:00
$taskstatic -> duration_effective = $lines [ $i ] -> duration_effective ;
2021-10-15 08:24:56 +00:00
$taskstatic -> budget_amount = $lines [ $i ] -> budget_amount ;
2024-07-03 01:29:05 +00:00
$taskstatic -> billable = $lines [ $i ] -> billable ;
2024-11-16 22:34:10 +00:00
$taskstatic -> status = $lines [ $i ] -> status ;
2024-11-16 16:53:53 +00:00
$taskstatic -> fk_statut = $lines [ $i ] -> fk_statut ;
2019-08-10 13:41:21 +00:00
2023-06-04 16:54:38 +00:00
// Action column
2026-04-23 15:41:15 +00:00
if ( $conf -> main_checkbox_left_column ) {
2023-06-04 16:54:38 +00:00
print '<td class="nowrap center">' ;
$selected = 0 ;
if ( in_array ( $lines [ $i ] -> id , $arrayofselected )) {
$selected = 1 ;
}
print '<input id="cb' . $lines [ $i ] -> id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $lines [ $i ] -> id . '"' . ( $selected ? ' checked="checked"' : '' ) . '>' ;
print '</td>' ;
}
2019-03-29 13:34:55 +00:00
2021-02-23 21:03:23 +00:00
if ( $showproject ) {
2014-03-11 08:43:26 +00:00
// Project ref
2022-06-21 09:11:28 +00:00
print '<td class="nowraponall">' ;
2015-12-04 17:33:57 +00:00
//if ($showlineingray) print '<i>';
2023-10-15 13:32:35 +00:00
if ( $lines [ $i ] -> public || in_array ( $lines [ $i ] -> fk_project , $projectsArrayId ) || $user -> hasRight ( 'projet' , 'all' , 'lire' )) {
2021-02-23 21:03:23 +00:00
print $projectstatic -> getNomUrl ( 1 );
} else {
print $projectstatic -> getNomUrl ( 1 , 'nolink' );
}
2015-12-04 17:33:57 +00:00
//if ($showlineingray) print '</i>';
2013-04-12 09:09:53 +00:00
print " </td> " ;
2014-03-11 08:43:26 +00:00
2014-03-11 19:38:29 +00:00
// Project status
2014-03-11 08:43:26 +00:00
print '<td>' ;
2019-11-13 18:35:02 +00:00
$projectstatic -> statut = $lines [ $i ] -> projectstatus ;
2014-03-11 08:43:26 +00:00
print $projectstatic -> getLibStatut ( 2 );
print " </td> " ;
2013-04-12 09:09:53 +00:00
}
// Ref of task
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.ref' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowraponall">' ;
if ( $showlineingray ) {
2020-04-10 08:59:32 +00:00
print '<i>' . img_object ( '' , 'projecttask' ) . ' ' . $lines [ $i ] -> ref . '</i>' ;
2020-03-24 18:50:01 +00:00
} else {
print $taskstatic -> getNomUrl ( 1 , 'withproject' );
}
print '</td>' ;
2013-04-12 09:09:53 +00:00
}
// Title of task
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.label' ][ 'checked' ])) {
2022-01-15 12:08:15 +00:00
$labeltoshow = '' ;
2021-02-23 21:03:23 +00:00
if ( $showlineingray ) {
2022-01-15 12:08:15 +00:00
$labeltoshow .= '<i>' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
//else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/task.php?id='.$lines[$i]->id.'&withproject=1">';
for ( $k = 0 ; $k < $level ; $k ++ ) {
2022-01-15 12:08:15 +00:00
$labeltoshow .= '<div class="marginleftonly">' ;
2020-03-24 18:50:01 +00:00
}
2022-01-15 12:08:15 +00:00
$labeltoshow .= dol_escape_htmltag ( $lines [ $i ] -> label );
2020-03-24 18:50:01 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
2022-01-15 12:08:15 +00:00
$labeltoshow .= '</div>' ;
2020-03-24 18:50:01 +00:00
}
2021-02-23 21:03:23 +00:00
if ( $showlineingray ) {
2022-01-15 12:08:15 +00:00
$labeltoshow .= '</i>' ;
2021-02-23 21:03:23 +00:00
}
2022-01-15 12:08:15 +00:00
print '<td class="tdoverflowmax200" title="' . dol_escape_htmltag ( $labeltoshow ) . '">' ;
print $labeltoshow ;
2020-03-24 18:50:01 +00:00
print " </td> \n " ;
2013-04-12 09:09:53 +00:00
}
2020-03-24 18:50:01 +00:00
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.description' ][ 'checked' ])) {
2022-06-21 09:11:28 +00:00
print '<td class="tdoverflowmax200" title="' . dol_escape_htmltag ( $lines [ $i ] -> description ) . '">' ;
2020-03-24 18:50:01 +00:00
print $lines [ $i ] -> description ;
print " </td> \n " ;
2019-07-24 15:15:25 +00:00
}
2013-04-12 09:09:53 +00:00
// Date start
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.dateo' ][ 'checked' ])) {
2022-06-21 09:11:28 +00:00
print '<td class="center nowraponall">' ;
2020-03-24 18:50:01 +00:00
print dol_print_date ( $lines [ $i ] -> date_start , 'dayhour' );
print '</td>' ;
}
2013-04-12 09:09:53 +00:00
// Date end
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.datee' ][ 'checked' ])) {
2022-06-21 09:11:28 +00:00
print '<td class="center nowraponall">' ;
2020-03-24 18:50:01 +00:00
print dol_print_date ( $lines [ $i ] -> date_end , 'dayhour' );
2021-02-23 21:03:23 +00:00
if ( $taskstatic -> hasDelay ()) {
2020-03-24 18:50:01 +00:00
print img_warning ( $langs -> trans ( " Late " ));
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
print '</td>' ;
}
2013-04-12 09:09:53 +00:00
2019-11-13 18:35:02 +00:00
$plannedworkloadoutputformat = 'allhourmin' ;
$timespentoutputformat = 'allhourmin' ;
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_PLANNED_WORKLOAD_FORMAT' )) {
2024-01-05 03:18:53 +00:00
$plannedworkloadoutputformat = getDolGlobalString ( 'PROJECT_PLANNED_WORKLOAD_FORMAT' );
2021-02-23 21:03:23 +00:00
}
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMES_SPENT_FORMAT' )) {
2024-01-05 03:18:53 +00:00
$timespentoutputformat = getDolGlobalString ( 'PROJECT_TIME_SPENT_FORMAT' );
2021-02-23 21:03:23 +00:00
}
2015-02-28 18:02:03 +00:00
2013-10-30 20:44:04 +00:00
// Planned Workload (in working hours)
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
$fullhour = convertSecondToTime ( $lines [ $i ] -> planned_workload , $plannedworkloadoutputformat );
$workingdelay = convertSecondToTime ( $lines [ $i ] -> planned_workload , 'all' , 86400 , 7 ); // TODO Replace 86400 and 7 to take account working hours per day and working day per weeks
if ( $lines [ $i ] -> planned_workload != '' ) {
print $fullhour ;
// TODO Add delay taking account of working hours per day and working day per week
//if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
}
//else print '--:--';
print '</td>' ;
2013-10-30 20:44:04 +00:00
}
2013-05-13 15:08:36 +00:00
2013-04-12 09:09:53 +00:00
// Time spent
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.duration_effective' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
2021-02-23 21:03:23 +00:00
if ( $showlineingray ) {
2020-03-24 18:50:01 +00:00
print '<i>' ;
2021-02-23 21:03:23 +00:00
} else {
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . $lines [ $i ] -> id . ( $showproject ? '' : '&withproject=1' ) . '">' ;
}
2023-06-29 13:54:09 +00:00
if ( $lines [ $i ] -> duration_effective ) {
print convertSecondToTime ( $lines [ $i ] -> duration_effective , $timespentoutputformat );
2021-02-23 21:03:23 +00:00
} else {
print '--:--' ;
}
if ( $showlineingray ) {
2020-03-24 18:50:01 +00:00
print '</i>' ;
2021-02-23 21:03:23 +00:00
} else {
print '</a>' ;
}
2020-03-24 18:50:01 +00:00
print '</td>' ;
}
2013-04-12 09:09:53 +00:00
2023-06-29 13:54:09 +00:00
// Progress calculated (Note: ->duration_effective is time spent)
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress_calculated' ][ 'checked' ])) {
2023-12-04 11:05:28 +00:00
$s = '' ;
$shtml = '' ;
2023-06-29 13:54:09 +00:00
if ( $lines [ $i ] -> planned_workload || $lines [ $i ] -> duration_effective ) {
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> planned_workload ) {
2024-03-23 00:12:43 +00:00
$s = round ( 100 * ( float ) $lines [ $i ] -> duration_effective / ( float ) $lines [ $i ] -> planned_workload , 2 ) . ' %' ;
2023-06-16 11:16:35 +00:00
$shtml = $s ;
2021-02-23 21:03:23 +00:00
} else {
2023-06-16 11:16:35 +00:00
$s = $langs -> trans ( 'WorkloadNotDefined' );
$shtml = '<span class="opacitymedium">' . $s . '</span>' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
}
2023-06-16 11:16:35 +00:00
print '<td class="right tdoverflowmax100" title="' . dol_escape_htmltag ( $s ) . '">' ;
print $shtml ;
2020-03-24 18:50:01 +00:00
print '</td>' ;
2014-12-21 13:58:18 +00:00
}
2013-10-30 20:44:04 +00:00
2016-01-18 14:56:51 +00:00
// Progress declared
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
if ( $lines [ $i ] -> progress != '' ) {
print getTaskProgressBadge ( $taskstatic );
}
print '</td>' ;
2016-01-18 14:56:51 +00:00
}
2019-08-10 13:41:21 +00:00
// resume
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress_summary' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
2023-06-29 13:54:09 +00:00
if ( $lines [ $i ] -> progress != '' && $lines [ $i ] -> duration_effective ) {
2020-03-24 18:50:01 +00:00
print getTaskProgressView ( $taskstatic , false , false );
}
print '</td>' ;
}
2019-08-10 13:41:21 +00:00
2025-01-21 11:03:17 +00:00
// Status
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.fk_statut' ][ 'checked' ])) {
print '<td class="center">' ;
print $taskstatic -> getLibStatut ( 4 );
print '</td>' ;
}
2021-02-23 21:03:23 +00:00
if ( $showbilltime ) {
2020-10-31 13:32:18 +00:00
// Time not billed
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.tobill' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
if ( $lines [ $i ] -> usage_bill_time ) {
print convertSecondToTime ( $lines [ $i ] -> tobill , 'allhourmin' );
$total_projectlinesa_tobill += $lines [ $i ] -> tobill ;
} else {
2020-04-10 08:59:32 +00:00
print '<span class="opacitymedium">' . $langs -> trans ( " NA " ) . '</span>' ;
2020-03-24 18:50:01 +00:00
}
print '</td>' ;
}
2019-03-29 13:34:55 +00:00
2020-10-31 13:32:18 +00:00
// Time billed
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.billed' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
if ( $lines [ $i ] -> usage_bill_time ) {
print convertSecondToTime ( $lines [ $i ] -> billed , 'allhourmin' );
$total_projectlinesa_billed += $lines [ $i ] -> billed ;
} else {
2020-04-10 08:59:32 +00:00
print '<span class="opacitymedium">' . $langs -> trans ( " NA " ) . '</span>' ;
2020-03-24 18:50:01 +00:00
}
print '</td>' ;
}
2019-03-29 13:34:55 +00:00
}
2022-07-26 08:54:03 +00:00
// Budget task
2022-01-21 14:40:37 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.budget_amount' ][ 'checked' ])) {
2021-10-15 08:24:56 +00:00
print '<td class="center">' ;
2022-07-26 08:54:03 +00:00
if ( $lines [ $i ] -> budget_amount ) {
print '<span class="amount">' . price ( $lines [ $i ] -> budget_amount , 0 , $langs , 1 , 0 , 0 , $conf -> currency ) . '</span>' ;
$total_budget_amount += $lines [ $i ] -> budget_amount ;
}
2021-10-15 08:24:56 +00:00
print '</td>' ;
}
2021-03-04 09:33:18 +00:00
2018-05-25 08:50:16 +00:00
// Contacts of task
2021-03-04 09:15:41 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 'c.assigned' ][ 'checked' ])) {
2021-06-30 13:00:04 +00:00
print '<td class="center">' ;
2022-01-15 11:56:19 +00:00
$ifisrt = 1 ;
2021-02-23 21:03:23 +00:00
foreach ( array ( 'internal' , 'external' ) as $source ) {
2023-06-16 10:49:03 +00:00
//$tab = $lines[$i]->liste_contact(-1, $source);
$tab = $lines [ $i ] -> liste_contact ( - 1 , $source , 0 , '' , 1 );
2022-01-15 11:26:08 +00:00
$numcontact = count ( $tab );
if ( ! empty ( $numcontact )) {
2019-11-13 18:35:02 +00:00
foreach ( $tab as $contacttask ) {
2021-02-23 21:03:23 +00:00
if ( $source == 'internal' ) {
$c = new User ( $db );
} else {
$c = new Contact ( $db );
}
2018-05-25 08:50:16 +00:00
$c -> fetch ( $contacttask [ 'id' ]);
2021-03-04 09:36:17 +00:00
if ( ! empty ( $c -> photo )) {
2022-01-15 11:56:19 +00:00
if ( get_class ( $c ) == 'User' ) {
2025-06-22 18:13:01 +00:00
/** @var User $c */
'@phan-var-force User $c' ;
2022-01-15 11:56:19 +00:00
print $c -> getNomUrl ( - 2 , '' , 0 , 0 , 24 , 1 , '' , ( $ifisrt ? '' : 'notfirst' ));
} else {
2025-06-22 18:13:01 +00:00
/** @var Contact $c */
'@phan-var-force Contact $c' ;
print $c -> getNomUrl ( - 2 , '' , 0 , '' , - 1 , 0 , ( $ifisrt ? '' : 'notfirst' ));
2022-01-15 11:56:19 +00:00
}
2021-03-04 09:36:17 +00:00
} else {
2021-03-04 09:15:41 +00:00
if ( get_class ( $c ) == 'User' ) {
2025-06-22 18:13:01 +00:00
/** @var User $c */
'@phan-var-force User $c' ;
2022-01-15 11:56:19 +00:00
print $c -> getNomUrl ( 2 , '' , 0 , 0 , 24 , 1 , '' , ( $ifisrt ? '' : 'notfirst' ));
2021-03-04 09:36:17 +00:00
} else {
2025-06-22 18:13:01 +00:00
/** @var Contact $c */
'@phan-var-force Contact $c' ;
print $c -> getNomUrl ( 2 , '' , 0 , '' , - 1 , 0 , ( $ifisrt ? '' : 'notfirst' ));
2021-03-04 09:15:41 +00:00
}
}
2022-01-15 11:56:19 +00:00
$ifisrt = 0 ;
2018-05-25 08:50:16 +00:00
}
2018-05-21 09:03:48 +00:00
}
}
2018-05-25 08:50:16 +00:00
print '</td>' ;
2018-05-21 09:03:48 +00:00
}
2024-07-03 01:29:05 +00:00
// Billable
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.billable' ][ 'checked' ])) {
print '<td class="center">' ;
if ( $lines [ $i ] -> billable ) {
print '<span>' . $langs -> trans ( 'Yes' ) . '</span>' ;
} else {
print '<span>' . $langs -> trans ( 'No' ) . '</span>' ;
}
print '</td>' ;
}
2020-03-24 18:50:01 +00:00
// Extra fields
2020-04-10 08:59:32 +00:00
$extrafieldsobjectkey = $taskstatic -> table_element ;
2023-11-17 15:39:49 +00:00
$extrafieldsobjectprefix = 'efpt.' ;
2024-03-14 13:59:04 +00:00
$obj = $lines [ $i ];
2025-08-22 03:18:25 +00:00
$object = $lines [ $i ];
2020-03-24 18:50:01 +00:00
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php' ;
// Fields from hook
2024-03-12 23:30:00 +00:00
$parameters = array ( 'arrayfields' => $arrayfields , 'obj' => $lines [ $i ]);
2020-04-10 08:59:32 +00:00
$reshook = $hookmanager -> executeHooks ( 'printFieldListValue' , $parameters ); // Note that $action and $object may have been modified by hook
2020-03-24 18:50:01 +00:00
print $hookmanager -> resPrint ;
2013-04-12 09:09:53 +00:00
// Tick to drag and drop
2020-11-21 22:36:20 +00:00
print '<td class="tdlineupdown center"></td>' ;
2013-04-12 09:09:53 +00:00
2022-12-07 11:49:54 +00:00
// Action column
2026-04-23 15:41:15 +00:00
if ( ! $conf -> main_checkbox_left_column ) {
2023-06-04 16:54:38 +00:00
print '<td class="nowrap center">' ;
$selected = 0 ;
if ( in_array ( $lines [ $i ] -> id , $arrayofselected )) {
$selected = 1 ;
}
print '<input id="cb' . $lines [ $i ] -> id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $lines [ $i ] -> id . '"' . ( $selected ? ' checked="checked"' : '' ) . '>' ;
2022-12-07 11:49:54 +00:00
2023-06-04 16:54:38 +00:00
print '</td>' ;
}
2022-12-07 11:49:54 +00:00
2013-04-12 09:09:53 +00:00
print " </tr> \n " ;
2021-02-23 21:03:23 +00:00
if ( ! $showlineingray ) {
$inc ++ ;
}
2013-04-12 09:09:53 +00:00
2021-02-23 21:03:23 +00:00
if ( $level >= 0 ) { // Call sublevels
2017-10-07 11:09:31 +00:00
$level ++ ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> id ) {
2024-09-26 00:48:16 +00:00
projectLinesa ( $inc , $lines [ $i ] -> id , $lines , $level , '' , $showproject , $taskrole , $projectsListId , $addordertick , $projectidfortotallink , '' , $showbilltime , $arrayfields );
2021-02-23 21:03:23 +00:00
}
2017-10-07 11:09:31 +00:00
$level -- ;
2016-01-19 22:45:03 +00:00
}
2017-06-02 10:27:46 +00:00
2023-06-29 13:54:09 +00:00
$total_projectlinesa_spent += $lines [ $i ] -> duration_effective ;
2014-03-17 14:13:24 +00:00
$total_projectlinesa_planned += $lines [ $i ] -> planned_workload ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> planned_workload ) {
2023-06-29 13:54:09 +00:00
$total_projectlinesa_spent_if_planned += $lines [ $i ] -> duration_effective ;
2021-02-23 21:03:23 +00:00
}
if ( $lines [ $i ] -> planned_workload ) {
2024-03-23 00:12:43 +00:00
$total_projectlinesa_declared_if_planned += ( float ) $lines [ $i ] -> planned_workload * $lines [ $i ] -> progress / 100 ;
2021-02-23 21:03:23 +00:00
}
2013-04-12 09:09:53 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2013-04-12 09:09:53 +00:00
//$level--;
}
}
2023-06-16 11:07:19 +00:00
// Total line
2021-10-15 08:53:17 +00:00
if (( $total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0 || $total_projectlinesa_tobill > 0 || $total_projectlinesa_billed > 0 || $total_budget_amount > 0 )
2021-02-23 21:03:23 +00:00
&& $level <= 0 ) {
2015-04-09 08:37:54 +00:00
print '<tr class="liste_total nodrag nodrop">' ;
2023-06-04 16:54:38 +00:00
2026-04-23 15:41:15 +00:00
if ( $conf -> main_checkbox_left_column ) {
2023-07-19 00:03:34 +00:00
print '<td class="liste_total"></td>' ;
2023-06-04 16:54:38 +00:00
}
2013-04-15 23:13:20 +00:00
print '<td class="liste_total">' . $langs -> trans ( " Total " ) . '</td>' ;
2021-02-23 21:03:23 +00:00
if ( $showproject ) {
print '<td></td><td></td>' ;
}
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.label' ][ 'checked' ])) {
print '<td></td>' ;
}
2023-07-19 00:03:34 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.description' ][ 'checked' ])) {
2021-02-23 21:03:23 +00:00
print '<td></td>' ;
}
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.dateo' ][ 'checked' ])) {
print '<td></td>' ;
}
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.datee' ][ 'checked' ])) {
print '<td></td>' ;
}
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
print convertSecondToTime ( $total_projectlinesa_planned , 'allhourmin' );
print '</td>' ;
}
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.duration_effective' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
2021-02-23 21:03:23 +00:00
if ( $projectidfortotallink > 0 ) {
2020-04-10 08:59:32 +00:00
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?projectid=' . $projectidfortotallink . ( $showproject ? '' : '&withproject=1' ) . '">' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
print convertSecondToTime ( $total_projectlinesa_spent , 'allhourmin' );
2021-02-23 21:03:23 +00:00
if ( $projectidfortotallink > 0 ) {
2020-03-24 18:50:01 +00:00
print '</a>' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
print '</td>' ;
}
2019-09-08 16:03:14 +00:00
2024-09-22 22:37:30 +00:00
$totalCalculatedProgress = 0 ;
$totalAverageDeclaredProgress = 0 ;
$badgeClass = '' ;
$progressBarClass = '' ;
2020-10-31 13:32:18 +00:00
if ( $total_projectlinesa_planned ) {
$totalAverageDeclaredProgress = round ( 100 * $total_projectlinesa_declared_if_planned / $total_projectlinesa_planned , 2 );
$totalCalculatedProgress = round ( 100 * $total_projectlinesa_spent / $total_projectlinesa_planned , 2 );
2024-01-13 18:48:20 +00:00
// this conf is actually hidden, by default we use 10% for "be careful or warning"
2023-11-27 10:39:32 +00:00
$warningRatio = getDolGlobalString ( 'PROJECT_TIME_SPEND_WARNING_PERCENT' ) ? ( 1 + $conf -> global -> PROJECT_TIME_SPEND_WARNING_PERCENT / 100 ) : 1.10 ;
2020-10-31 13:32:18 +00:00
// define progress color according to time spend vs workload
$progressBarClass = 'progress-bar-info' ;
$badgeClass = 'badge ' ;
if ( $totalCalculatedProgress > $totalAverageDeclaredProgress ) {
$progressBarClass = 'progress-bar-danger' ;
$badgeClass .= 'badge-danger' ;
} elseif ( $totalCalculatedProgress * $warningRatio >= $totalAverageDeclaredProgress ) { // warning if close at 1%
$progressBarClass = 'progress-bar-warning' ;
$badgeClass .= 'badge-warning' ;
} else {
$progressBarClass = 'progress-bar-success' ;
$badgeClass .= 'badge-success' ;
}
}
2019-09-08 16:03:14 +00:00
2021-09-24 00:31:15 +00:00
// Computed progress
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress_calculated' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
2021-02-23 21:03:23 +00:00
if ( $total_projectlinesa_planned ) {
2020-04-10 08:59:32 +00:00
print $totalCalculatedProgress . ' %' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
print '</td>' ;
}
2021-09-24 00:31:15 +00:00
// Declared progress
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
2021-02-23 21:03:23 +00:00
if ( $total_projectlinesa_planned ) {
2020-04-10 08:59:32 +00:00
print '<span class="' . $badgeClass . '" >' . $totalAverageDeclaredProgress . ' %</span>' ;
2021-02-23 21:03:23 +00:00
}
2020-03-24 18:50:01 +00:00
print '</td>' ;
}
2019-09-08 16:03:14 +00:00
2022-07-26 08:54:03 +00:00
// Progress
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.progress_summary' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="right">' ;
if ( $total_projectlinesa_planned ) {
print '</span>' ;
2020-04-10 08:59:32 +00:00
print ' <div class="progress sm" title="' . $totalAverageDeclaredProgress . '%" >' ;
print ' <div class="progress-bar ' . $progressBarClass . '" style="width: ' . $totalAverageDeclaredProgress . '%"></div>' ;
2020-03-24 18:50:01 +00:00
print ' </div>' ;
print '</div>' ;
}
print '</td>' ;
}
2019-09-08 16:03:14 +00:00
2021-02-23 21:03:23 +00:00
if ( $showbilltime ) {
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.tobill' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
print convertSecondToTime ( $total_projectlinesa_tobill , 'allhourmin' );
print '</td>' ;
}
2020-04-10 08:59:32 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.billed' ][ 'checked' ])) {
2020-03-24 18:50:01 +00:00
print '<td class="nowrap liste_total right">' ;
print convertSecondToTime ( $total_projectlinesa_billed , 'allhourmin' );
print '</td>' ;
}
2019-03-29 13:34:55 +00:00
}
2021-10-15 08:24:56 +00:00
2022-07-26 08:54:03 +00:00
// Budget task
2021-10-15 08:24:56 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 't.budget_amount' ][ 'checked' ])) {
2021-10-15 08:53:17 +00:00
print '<td class="nowrap liste_total center">' ;
2024-03-19 17:57:52 +00:00
if ( strcmp (( string ) $total_budget_amount , '' )) {
2022-07-26 08:54:03 +00:00
print price ( $total_budget_amount , 0 , $langs , 1 , 0 , 0 , $conf -> currency );
}
2021-10-15 08:24:56 +00:00
print '</td>' ;
}
2021-03-04 09:33:18 +00:00
// Contacts of task for backward compatibility,
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_SHOW_CONTACTS_IN_LIST' )) {
2021-03-04 09:33:18 +00:00
print '<td></td>' ;
}
2018-05-25 08:50:16 +00:00
// Contacts of task
2021-03-04 09:15:41 +00:00
if ( count ( $arrayfields ) > 0 && ! empty ( $arrayfields [ 'c.assigned' ][ 'checked' ])) {
2018-05-25 08:50:16 +00:00
print '<td></td>' ;
}
2023-02-28 14:46:42 +00:00
2023-06-04 16:54:38 +00:00
// Check if Extrafields is totalizable
2023-09-13 16:16:31 +00:00
if ( ! empty ( $extrafields -> attributes [ 'projet_task' ][ 'totalizable' ])) {
foreach ( $extrafields -> attributes [ 'projet_task' ][ 'totalizable' ] as $key => $value ) {
2024-01-25 18:14:55 +00:00
if ( ! empty ( $arrayfields [ 'efpt.' . $key ][ 'checked' ]) && $arrayfields [ 'efpt.' . $key ][ 'checked' ] == 1 ) {
2023-09-13 16:16:31 +00:00
print '<td class="right">' ;
if ( $value == 1 ) {
print empty ( $totalarray [ 'totalizable' ][ $key ][ 'total' ]) ? '' : $totalarray [ 'totalizable' ][ $key ][ 'total' ];
}
print '</td>' ;
2023-02-28 14:46:42 +00:00
}
}
}
2023-06-16 11:12:58 +00:00
// Column for the drag and drop
2023-07-19 00:03:34 +00:00
print '<td class="liste_total"></td>' ;
2023-06-16 11:07:19 +00:00
2026-04-23 15:41:15 +00:00
if ( ! $conf -> main_checkbox_left_column ) {
2023-07-19 00:03:34 +00:00
print '<td class="liste_total"></td>' ;
2023-06-04 16:54:38 +00:00
}
2013-04-15 23:13:20 +00:00
print '</tr>' ;
2013-04-12 09:09:53 +00:00
}
return $inc ;
2009-01-14 23:36:51 +00:00
}
2009-07-28 13:37:28 +00:00
2017-11-22 20:19:40 +00:00
/**
2024-01-13 18:48:20 +00:00
* Output a task line into a pertime input mode
2017-11-22 20:19:40 +00:00
*
2024-11-21 21:36:00 +00:00
* @ param int $inc Line number ( start to 0 , then increased by recursive call )
2024-08-20 07:46:59 +00:00
* @ param int $parent Id of parent task to show ( 0 to show all )
2024-09-22 22:37:30 +00:00
* @ param ? User $fuser Restrict list to user if defined
2017-11-22 20:19:40 +00:00
* @ param Task [] $lines Array of lines
* @ param int $level Level ( start to 0 , then increased / decrease by recursive call )
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $projectsrole Array of roles user has on project
* @ param array < int , string > $tasksrole Array of roles user has on task
2022-12-21 20:09:50 +00:00
* @ param string $mine Show only task lines I am assigned to
2024-09-22 22:37:30 +00:00
* @ param int < 0 , 1 > $restricteditformytask 0 = No restriction , 1 = Enable add time only if task is a task i am affected to
2017-11-22 20:19:40 +00:00
* @ param int $preselectedday Preselected day
2024-09-22 22:37:30 +00:00
* @ param array < int , array { morning : int < 0 , 1 > , afternoon : int < 0 , 1 > } > $isavailable Array with data that say if user is available for several days for morning and afternoon
2017-11-22 20:19:40 +00:00
* @ param int $oldprojectforbreak Old project id of last project break
2024-09-22 22:37:30 +00:00
* @ return array < int , int > Array with time spent for $fuser for each day of week on tasks in $lines and subtasks
2017-11-22 20:19:40 +00:00
*/
2019-01-27 14:20:16 +00:00
function projectLinesPerAction ( & $inc , $parent , $fuser , $lines , & $level , & $projectsrole , & $tasksrole , $mine , $restricteditformytask , $preselectedday , & $isavailable , $oldprojectforbreak = 0 )
2017-11-22 20:19:40 +00:00
{
2020-03-23 19:16:51 +00:00
global $conf , $db , $user , $langs ;
2017-11-22 20:19:40 +00:00
global $form , $formother , $projectstatic , $taskstatic , $thirdpartystatic ;
2024-09-22 22:37:30 +00:00
'
@ phan - var - force FormOther $formother
@ phan - var - force Project $projectstatic
@ phan - var - force Task $taskstatic
@ phan - var - force Societe $thirdpartystatic
' ;
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$lastprojectid = 0 ;
$totalforeachline = array ();
$workloadforid = array ();
$lineswithoutlevel0 = array ();
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$numlines = count ( $lines );
2017-11-22 20:19:40 +00:00
// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
2021-02-23 21:03:23 +00:00
if ( $parent == 0 ) { // Always and only if at first level
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $lines [ $i ] -> fk_task_parent ) {
$lineswithoutlevel0 [] = $lines [ $i ];
}
2017-11-22 20:19:40 +00:00
}
}
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak )) {
2023-11-27 10:39:32 +00:00
$oldprojectforbreak = ( ! getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' ) ? 0 : - 1 ); // 0 to start break , -1 no break
2017-11-22 20:19:40 +00:00
}
//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $parent == 0 ) {
$level = 0 ;
}
2017-11-22 20:19:40 +00:00
//if ($lines[$i]->fk_task_parent == $parent)
//{
2019-10-20 09:17:54 +00:00
// If we want all or we have a role on task, we show it
2021-02-23 21:03:23 +00:00
if ( empty ( $mine ) || ! empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2019-10-20 09:17:54 +00:00
//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Break on a new project
2021-02-23 21:03:23 +00:00
if ( $parent == 0 && $lines [ $i ] -> fk_project != $lastprojectid ) {
2019-11-13 18:35:02 +00:00
$lastprojectid = $lines [ $i ] -> fk_project ;
2021-02-23 21:03:23 +00:00
if ( $preselectedday ) {
2019-10-20 09:17:54 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
2017-11-22 20:19:40 +00:00
}
2019-10-20 09:17:54 +00:00
}
2017-11-22 20:19:40 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $workloadforid [ $projectstatic -> id ])) {
if ( $preselectedday ) {
2023-04-07 01:08:02 +00:00
$projectstatic -> loadTimeSpent ( $preselectedday , 0 , $fuser -> id ); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
2019-11-13 18:35:02 +00:00
$workloadforid [ $projectstatic -> id ] = 1 ;
2017-11-22 20:19:40 +00:00
}
2019-10-20 09:17:54 +00:00
}
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
$projectstatic -> ref = $lines [ $i ] -> project_ref ;
$projectstatic -> title = $lines [ $i ] -> project_label ;
$projectstatic -> public = $lines [ $i ] -> public ;
2022-11-09 21:40:53 +00:00
$projectstatic -> status = $lines [ $i ] -> project -> status ;
2017-11-22 20:19:40 +00:00
2022-11-09 21:40:53 +00:00
$taskstatic -> id = $lines [ $i ] -> fk_statut ;
2019-11-13 18:35:02 +00:00
$taskstatic -> ref = ( $lines [ $i ] -> task_ref ? $lines [ $i ] -> task_ref : $lines [ $i ] -> task_id );
$taskstatic -> label = $lines [ $i ] -> task_label ;
$taskstatic -> date_start = $lines [ $i ] -> date_start ;
$taskstatic -> date_end = $lines [ $i ] -> date_end ;
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$thirdpartystatic -> id = $lines [ $i ] -> socid ;
$thirdpartystatic -> name = $lines [ $i ] -> thirdparty_name ;
$thirdpartystatic -> email = $lines [ $i ] -> thirdparty_email ;
2017-11-22 20:19:40 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak ) || ( $oldprojectforbreak != - 1 && $oldprojectforbreak != $projectstatic -> id )) {
2020-03-24 12:06:59 +00:00
print '<tr class="oddeven trforbreak nobold">' . " \n " ;
2019-10-20 09:17:54 +00:00
print '<td colspan="11">' ;
print $projectstatic -> getNomUrl ( 1 , '' , 0 , $langs -> transnoentitiesnoconv ( " YourRole " ) . ': ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
2021-02-23 21:03:23 +00:00
if ( $projectstatic -> title ) {
2019-10-20 09:17:54 +00:00
print ' - ' ;
print $projectstatic -> title ;
2017-11-22 20:19:40 +00:00
}
print '</td>' ;
2019-10-20 09:17:54 +00:00
print '</tr>' ;
}
2017-11-22 20:19:40 +00:00
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak != - 1 ) {
$oldprojectforbreak = $projectstatic -> id ;
}
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
print '<tr class="oddeven">' . " \n " ;
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// User
/*
print '<td class="nowrap">' ;
print $fuser -> getNomUrl ( 1 , 'withproject' , 'time' );
print '</td>' ;
*/
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Project
print " <td> " ;
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak == - 1 ) {
2019-10-20 09:17:54 +00:00
print $projectstatic -> getNomUrl ( 1 , '' , 0 , $langs -> transnoentitiesnoconv ( " YourRole " ) . ': ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
print '<br>' . $projectstatic -> title ;
}
print " </td> " ;
// Thirdparty
print '<td class="tdoverflowmax100">' ;
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print $thirdpartystatic -> getNomUrl ( 1 , 'project' , 10 );
}
2019-10-20 09:17:54 +00:00
print '</td>' ;
// Ref
print '<td>' ;
2023-11-20 10:41:02 +00:00
print '<!-- Task id = ' . $lines [ $i ] -> id . ' (projectlinesperaction) -->' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
2023-11-20 10:41:02 +00:00
print '<div class="marginleftonly">' ;
2021-02-23 21:03:23 +00:00
}
2019-10-20 09:17:54 +00:00
print $taskstatic -> getNomUrl ( 1 , 'withproject' , 'time' );
// Label task
print '<br>' ;
2026-05-05 11:50:20 +00:00
print '<div class="opacitymedium tdoverflowmax400 small" title="' . dol_escape_htmltag ( $taskstatic -> label ) . '">' . dol_escape_htmltag ( $taskstatic -> label ) . '</div>' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
2023-11-20 10:41:02 +00:00
print " </div> " ;
2021-02-23 21:03:23 +00:00
}
2019-10-20 09:17:54 +00:00
print " </td> \n " ;
// Date
print '<td class="center">' ;
print dol_print_date ( $lines [ $i ] -> timespent_datehour , 'day' );
print '</td>' ;
2021-03-01 19:37:16 +00:00
$disabledproject = 1 ;
$disabledtask = 1 ;
2019-10-20 09:17:54 +00:00
//print "x".$lines[$i]->fk_project;
//var_dump($lines[$i]);
//var_dump($projectsrole[$lines[$i]->fk_project]);
// If at least one role for project
2023-10-15 13:32:35 +00:00
if ( $lines [ $i ] -> public || ! empty ( $projectsrole [ $lines [ $i ] -> fk_project ]) || $user -> hasRight ( 'projet' , 'all' , 'creer' )) {
2019-11-13 18:35:02 +00:00
$disabledproject = 0 ;
$disabledtask = 0 ;
2019-10-20 09:17:54 +00:00
}
// If $restricteditformytask is on and I have no role on task, i disable edit
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask && empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2019-11-13 18:35:02 +00:00
$disabledtask = 1 ;
2019-10-20 09:17:54 +00:00
}
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Hour
print '<td class="nowrap center">' ;
print dol_print_date ( $lines [ $i ] -> timespent_datehour , 'hour' );
print '</td>' ;
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$cssonholiday = '' ;
2021-02-23 21:03:23 +00:00
if ( ! $isavailable [ $preselectedday ][ 'morning' ] && ! $isavailable [ $preselectedday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayallday ' ;
} elseif ( ! $isavailable [ $preselectedday ][ 'morning' ]) {
$cssonholiday .= 'onholidaymorning ' ;
} elseif ( ! $isavailable [ $preselectedday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayafternoon ' ;
}
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Duration
2019-11-13 18:35:02 +00:00
print '<td class="duration' . ( $cssonholiday ? ' ' . $cssonholiday : '' ) . ' center">' ;
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
$dayWorkLoad = $lines [ $i ] -> timespent_duration ;
2024-09-22 22:37:30 +00:00
if ( ! array_key_exists ( $preselectedday , $totalforeachline )) {
$totalforeachline [ $preselectedday ] = 0 ;
}
2019-11-13 18:35:02 +00:00
$totalforeachline [ $preselectedday ] += $lines [ $i ] -> timespent_duration ;
2017-11-22 20:19:40 +00:00
2019-11-13 18:35:02 +00:00
$alreadyspent = '' ;
2021-02-23 21:03:23 +00:00
if ( $dayWorkLoad > 0 ) {
$alreadyspent = convertSecondToTime ( $lines [ $i ] -> timespent_duration , 'allhourmin' );
}
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
print convertSecondToTime ( $lines [ $i ] -> timespent_duration , 'allhourmin' );
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
print '</td>' ;
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Note
print '<td class="center">' ;
2019-11-13 18:35:02 +00:00
print '<textarea name="' . $lines [ $i ] -> id . 'note" rows="' . ROWS_2 . '" id="' . $lines [ $i ] -> id . 'note"' . ( $disabledtask ? ' disabled="disabled"' : '' ) . '>' ;
2019-10-20 09:17:54 +00:00
print $lines [ $i ] -> timespent_note ;
print '</textarea>' ;
print '</td>' ;
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
// Warning
print '<td class="right">' ;
/* if (( ! $lines [ $i ] -> public ) && $disabledproject ) print $form -> textwithpicto ( '' , $langs -> trans ( " UserIsNotContactOfProject " ));
2020-01-27 01:13:12 +00:00
elseif ( $disabledtask )
2019-10-20 09:17:54 +00:00
{
$titleassigntask = $langs -> trans ( " AssignTaskToMe " );
if ( $fuser -> id != $user -> id ) $titleassigntask = $langs -> trans ( " AssignTaskToUser " , '...' );
2017-11-22 20:19:40 +00:00
2019-10-20 09:17:54 +00:00
print $form -> textwithpicto ( '' , $langs -> trans ( " TaskIsNotAssignedToUser " , $titleassigntask ));
} */
print '</td>' ;
print " </tr> \n " ;
}
2017-11-22 20:19:40 +00:00
//}
//else
//{
2024-03-12 23:30:00 +00:00
//$level--;
2017-11-22 20:19:40 +00:00
//}
}
return $totalforeachline ;
}
2012-02-15 22:08:20 +00:00
/**
2024-01-13 18:48:20 +00:00
* Output a task line into a pertime input mode
2012-02-15 22:08:20 +00:00
*
2024-11-21 21:36:00 +00:00
* @ param int $inc Line number ( start to 0 , then increased by recursive call )
2024-08-20 07:46:59 +00:00
* @ param int $parent Id of parent task to show ( 0 to show all )
2024-09-22 22:37:30 +00:00
* @ param ? User $fuser Restrict list to user if defined
2015-03-05 10:13:44 +00:00
* @ param Task [] $lines Array of lines
* @ param int $level Level ( start to 0 , then increased / decrease by recursive call )
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $projectsrole Array of roles user has on project
* @ param array < int , string > $tasksrole Array of roles user has on task
2024-09-22 22:37:30 +00:00
* @ param int < 0 , 1 > $mine Show only task lines I am assigned to
* @ param int < 0 , 2 > $restricteditformytask 0 = No restriction , 1 = Enable add time only if task is assigned to me , 2 = Enable add time only if tasks is assigned to me and hide others
2015-04-09 18:40:49 +00:00
* @ param int $preselectedday Preselected day
2024-09-22 22:37:30 +00:00
* @ param array < int , array { morning : int < 0 , 1 > , afternoon : int < 0 , 1 > } > $isavailable Array with data that say if user is available for several days for morning and afternoon
2017-11-02 14:33:04 +00:00
* @ param int $oldprojectforbreak Old project id of last project break
2025-01-27 12:52:55 +00:00
* @ param array < string , array < string , int | string >> $arrayfields Array of additional column
2019-10-06 12:41:52 +00:00
* @ param Extrafields $extrafields Object extrafields
2024-09-22 22:37:30 +00:00
* @ return array < int , int > Array with time spent for $fuser for each day of week on tasks in $lines and subtasks
2012-02-15 22:08:20 +00:00
*/
2019-10-06 12:41:52 +00:00
function projectLinesPerDay ( & $inc , $parent , $fuser , $lines , & $level , & $projectsrole , & $tasksrole , $mine , $restricteditformytask , $preselectedday , & $isavailable , $oldprojectforbreak = 0 , $arrayfields = array (), $extrafields = null )
2012-02-15 22:08:20 +00:00
{
2020-03-23 19:16:51 +00:00
global $conf , $db , $user , $langs ;
2016-10-18 10:16:12 +00:00
global $form , $formother , $projectstatic , $taskstatic , $thirdpartystatic ;
2024-09-22 22:37:30 +00:00
'
@ phan - var - force FormOther $formother
@ phan - var - force Project $projectstatic
@ phan - var - force Task $taskstatic
@ phan - var - force Societe $thirdpartystatic
' ;
2013-04-12 09:09:53 +00:00
2019-11-13 18:35:02 +00:00
$lastprojectid = 0 ;
$totalforeachday = array ();
$workloadforid = array ();
$lineswithoutlevel0 = array ();
2017-06-02 10:27:46 +00:00
2019-11-13 18:35:02 +00:00
$numlines = count ( $lines );
2017-06-02 10:27:46 +00:00
2016-07-08 15:06:12 +00:00
// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
2021-02-23 21:03:23 +00:00
if ( $parent == 0 ) { // Always and only if at first level
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $lines [ $i ] -> fk_task_parent ) {
$lineswithoutlevel0 [] = $lines [ $i ];
}
2017-10-07 11:09:31 +00:00
}
2017-06-02 10:27:46 +00:00
}
2016-07-08 15:06:12 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak )) {
2023-11-27 10:39:32 +00:00
$oldprojectforbreak = ( ! getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' ) ? 0 : - 1 ); // 0 to start break , -1 no break
2017-11-02 14:33:04 +00:00
}
2017-10-12 11:03:45 +00:00
2021-06-09 09:03:04 +00:00
$restrictBefore = null ;
2021-06-08 16:13:18 +00:00
2024-06-14 17:39:26 +00:00
if ( getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' )) {
2021-06-09 09:03:04 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2024-06-14 17:39:26 +00:00
$restrictBefore = dol_time_plus_duree ( dol_now (), - 1 * getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' ), 'm' );
2021-06-09 09:03:04 +00:00
}
2021-06-08 16:13:18 +00:00
2017-10-07 11:09:31 +00:00
//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $parent == 0 ) {
$level = 0 ;
}
2013-04-12 09:09:53 +00:00
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> fk_task_parent == $parent ) {
2020-10-31 13:32:18 +00:00
$obj = & $lines [ $i ]; // To display extrafields
2019-03-21 14:20:59 +00:00
2014-08-07 09:48:19 +00:00
// If we want all or we have a role on task, we show it
2021-02-23 21:03:23 +00:00
if ( empty ( $mine ) || ! empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2017-10-07 11:09:31 +00:00
//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
2017-06-02 10:27:46 +00:00
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask == 2 && empty ( $tasksrole [ $lines [ $i ] -> id ])) { // we have no role on task and we request to hide such cases
2018-09-16 11:28:37 +00:00
continue ;
}
2016-07-08 15:06:12 +00:00
// Break on a new project
2021-02-23 21:03:23 +00:00
if ( $parent == 0 && $lines [ $i ] -> fk_project != $lastprojectid ) {
2019-11-13 18:35:02 +00:00
$lastprojectid = $lines [ $i ] -> fk_project ;
2021-02-23 21:03:23 +00:00
if ( $preselectedday ) {
2017-10-07 11:09:31 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
}
}
2021-02-23 21:03:23 +00:00
if ( empty ( $workloadforid [ $projectstatic -> id ])) {
if ( $preselectedday ) {
2023-04-07 01:08:02 +00:00
$projectstatic -> loadTimeSpent ( $preselectedday , 0 , $fuser -> id ); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
2021-02-23 21:03:23 +00:00
$workloadforid [ $projectstatic -> id ] = 1 ;
2017-10-07 11:09:31 +00:00
}
}
2017-06-02 10:27:46 +00:00
2019-11-13 18:35:02 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
$projectstatic -> ref = $lines [ $i ] -> projectref ;
$projectstatic -> title = $lines [ $i ] -> projectlabel ;
$projectstatic -> public = $lines [ $i ] -> public ;
2021-01-26 14:16:06 +00:00
$projectstatic -> status = $lines [ $i ] -> projectstatus ;
2015-03-05 12:48:57 +00:00
2019-11-13 18:35:02 +00:00
$taskstatic -> id = $lines [ $i ] -> id ;
$taskstatic -> ref = ( $lines [ $i ] -> ref ? $lines [ $i ] -> ref : $lines [ $i ] -> id );
$taskstatic -> label = $lines [ $i ] -> label ;
$taskstatic -> date_start = $lines [ $i ] -> date_start ;
$taskstatic -> date_end = $lines [ $i ] -> date_end ;
2017-10-12 11:03:45 +00:00
2019-11-13 18:35:02 +00:00
$thirdpartystatic -> id = $lines [ $i ] -> socid ;
$thirdpartystatic -> name = $lines [ $i ] -> thirdparty_name ;
$thirdpartystatic -> email = $lines [ $i ] -> thirdparty_email ;
2017-10-12 11:03:45 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak ) || ( $oldprojectforbreak != - 1 && $oldprojectforbreak != $projectstatic -> id )) {
2020-10-31 13:32:18 +00:00
$addcolspan = 0 ;
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
$addcolspan ++ ;
}
if ( ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
$addcolspan ++ ;
}
foreach ( $arrayfields as $key => $val ) {
if ( $val [ 'checked' ] && substr ( $key , 0 , 5 ) == 'efpt.' ) {
$addcolspan ++ ;
}
2020-10-31 13:32:18 +00:00
}
2019-03-21 14:20:59 +00:00
2020-03-28 12:38:25 +00:00
print '<tr class="oddeven trforbreak nobold">' . " \n " ;
2019-11-13 18:35:02 +00:00
print '<td colspan="' . ( 7 + $addcolspan ) . '">' ;
2019-01-27 10:55:16 +00:00
print $projectstatic -> getNomUrl ( 1 , '' , 0 , '<strong>' . $langs -> transnoentitiesnoconv ( " YourRole " ) . ':</strong> ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print ' - ' . $thirdpartystatic -> getNomUrl ( 1 );
}
if ( $projectstatic -> title ) {
2017-10-12 11:03:45 +00:00
print ' - ' ;
2020-01-07 13:25:58 +00:00
print '<span class="secondary">' . $projectstatic -> title . '</span>' ;
2017-10-12 11:03:45 +00:00
}
2019-03-31 20:06:41 +00:00
/*
2021-02-23 21:03:23 +00:00
$colspan = 5 + ( empty ( $conf -> global -> PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT ) ? 0 : 2 );
print '<table class="">' ;
print '<tr class="liste_titre">' ;
// PROJECT fields
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.fk_opp_status' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.fk_opp_status' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.fk_opp_status' , " " , $param , '' , $sortfield , $sortorder , 'center ' );
if ( ! empty ( $arrayfields [ 'p.opp_amount' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.opp_amount' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.opp_amount' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.opp_percent' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.opp_percent' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.opp_percent' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.budget_amount' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.budget_amount' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.budget_amount' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.usage_bill_time' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.usage_bill_time' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.usage_bill_time' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
2021-02-23 21:03:23 +00:00
$extrafieldsobjectkey = 'projet' ;
$extrafieldsobjectprefix = 'efp.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_title.tpl.php' ;
print '</tr>' ;
print '<tr>' ;
// PROJECT fields
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.fk_opp_status' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
$code = dol_getIdFromCode ( $db , $lines [ $i ] -> fk_opp_status , 'c_lead_status' , 'rowid' , 'code' );
if ( $code ) print $langs -> trans ( " OppStatus " . $code );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.opp_amount' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> opp_amount , 0 , $langs , 1 , 0 , - 1 , $conf -> currency );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.opp_percent' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> opp_percent , 0 , $langs , 1 , 0 ) . ' %' ;
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.budget_amount' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> budget_amount , 0 , $langs , 1 , 0 , 0 , $conf -> currency );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.usage_bill_time' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print yn ( $lines [ $i ] -> usage_bill_time );
print " </td> \n " ;
}
$extrafieldsobjectkey = 'projet' ;
$extrafieldsobjectprefix = 'efp.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php' ;
print '</tr>' ;
print '</table>' ;
2019-03-21 14:20:59 +00:00
2019-03-31 20:06:41 +00:00
*/
2017-10-12 11:03:45 +00:00
print '</td>' ;
print '</tr>' ;
}
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak != - 1 ) {
$oldprojectforbreak = $projectstatic -> id ;
}
2015-03-05 12:48:57 +00:00
2019-11-21 16:05:06 +00:00
print '<tr class="oddeven" data-taskid="' . $lines [ $i ] -> id . '">' . " \n " ;
2017-06-02 10:27:46 +00:00
// User
2017-07-28 21:32:55 +00:00
/*
2017-06-02 10:27:46 +00:00
print '<td class="nowrap">' ;
print $fuser -> getNomUrl ( 1 , 'withproject' , 'time' );
print '</td>' ;
2017-07-28 21:32:55 +00:00
*/
2015-03-05 12:48:57 +00:00
2017-08-24 15:59:20 +00:00
// Project
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' )) {
2020-10-31 13:32:18 +00:00
print " <td> " ;
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak == - 1 ) {
print $projectstatic -> getNomUrl ( 1 , '' , 0 , $langs -> transnoentitiesnoconv ( " YourRole " ) . ': ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
}
2020-10-31 13:32:18 +00:00
print " </td> " ;
2019-03-31 20:06:41 +00:00
}
2017-08-24 15:59:20 +00:00
2017-10-09 16:18:34 +00:00
// Thirdparty
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' )) {
2020-10-31 13:32:18 +00:00
print '<td class="tdoverflowmax100">' ;
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print $thirdpartystatic -> getNomUrl ( 1 , 'project' , 10 );
}
2020-10-31 13:32:18 +00:00
print '</td>' ;
2019-03-31 20:06:41 +00:00
}
2017-08-24 15:59:20 +00:00
2017-10-06 12:38:33 +00:00
// Ref
print '<td>' ;
2023-11-20 10:41:02 +00:00
print '<!-- Task id = ' . $lines [ $i ] -> id . ' (projectlinesperday) -->' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print '<div class="marginleftonly">' ;
}
2017-10-06 12:38:33 +00:00
print $taskstatic -> getNomUrl ( 1 , 'withproject' , 'time' );
2014-08-07 09:48:19 +00:00
// Label task
2017-10-12 11:03:45 +00:00
print '<br>' ;
2026-05-05 11:50:20 +00:00
print '<div class="opacitymedium tdoverflowmax400 small" title="' . dol_escape_htmltag ( $taskstatic -> label ) . '">' . dol_escape_htmltag ( $taskstatic -> label ) . '</div>' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print " </div> " ;
}
2014-08-07 09:48:19 +00:00
print " </td> \n " ;
2014-08-07 23:19:03 +00:00
2020-10-31 13:32:18 +00:00
// TASK extrafields
$extrafieldsobjectkey = 'projet_task' ;
$extrafieldsobjectprefix = 'efpt.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php' ;
2019-03-21 14:20:59 +00:00
2020-10-31 13:32:18 +00:00
// Planned Workload
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
2020-10-31 13:32:18 +00:00
print '<td class="leftborder plannedworkload right">' ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> planned_workload ) {
print convertSecondToTime ( $lines [ $i ] -> planned_workload , 'allhourmin' );
} else {
print '--:--' ;
}
2020-10-31 13:32:18 +00:00
print '</td>' ;
}
2014-08-07 23:19:03 +00:00
2015-03-01 16:45:36 +00:00
// Progress declared %
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
2020-10-31 13:32:18 +00:00
print '<td class="right">' ;
print $formother -> select_percent ( $lines [ $i ] -> progress , $lines [ $i ] -> id . 'progress' );
print '</td>' ;
}
2014-08-07 23:19:03 +00:00
2021-04-10 11:29:24 +00:00
if ( ! empty ( $arrayfields [ 'timeconsumed' ][ 'checked' ])) {
// Time spent by everybody
print '<td class="right">' ;
2023-06-29 13:54:09 +00:00
// $lines[$i]->duration_effective is a denormalised field = summ of time spent by everybody for task. What we need is time consumed by user
if ( $lines [ $i ] -> duration_effective ) {
2021-04-10 11:29:24 +00:00
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . $lines [ $i ] -> id . '">' ;
2023-06-29 13:54:09 +00:00
print convertSecondToTime ( $lines [ $i ] -> duration_effective , 'allhourmin' );
2021-04-10 11:29:24 +00:00
print '</a>' ;
} else {
print '--:--' ;
}
print " </td> \n " ;
2015-03-01 16:45:36 +00:00
2021-04-10 11:29:24 +00:00
// Time spent by user
print '<td class="right">' ;
$tmptimespent = $taskstatic -> getSummaryOfTimeSpent ( $fuser -> id );
if ( $tmptimespent [ 'total_duration' ]) {
print convertSecondToTime ( $tmptimespent [ 'total_duration' ], 'allhourmin' );
} else {
print '--:--' ;
}
print " </td> \n " ;
2021-02-23 21:03:23 +00:00
}
2015-03-05 12:48:57 +00:00
2021-03-01 19:37:16 +00:00
$disabledproject = 1 ;
$disabledtask = 1 ;
2015-03-01 16:45:36 +00:00
//print "x".$lines[$i]->fk_project;
//var_dump($lines[$i]);
//var_dump($projectsrole[$lines[$i]->fk_project]);
// If at least one role for project
2023-10-15 13:32:35 +00:00
if ( $lines [ $i ] -> public || ! empty ( $projectsrole [ $lines [ $i ] -> fk_project ]) || $user -> hasRight ( 'projet' , 'all' , 'creer' )) {
2019-11-13 18:35:02 +00:00
$disabledproject = 0 ;
$disabledtask = 0 ;
2015-03-01 16:45:36 +00:00
}
// If $restricteditformytask is on and I have no role on task, i disable edit
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask && empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2019-11-13 18:35:02 +00:00
$disabledtask = 1 ;
2015-03-01 16:45:36 +00:00
}
2021-06-09 09:03:04 +00:00
if ( $restrictBefore && $preselectedday < $restrictBefore ) {
$disabledtask = 1 ;
}
2021-06-08 16:13:18 +00:00
2022-03-09 10:02:35 +00:00
// Select hour
2024-06-25 11:49:55 +00:00
print '<td class="nowraponall leftborder center minwidth150imp borderleft">' ;
2025-03-11 00:43:54 +00:00
$tableCell = $form -> selectDate ( $preselectedday , ( string ) $lines [ $i ] -> id , 1 , 1 , 2 , " addtime " , 0 , 0 , $disabledtask );
2015-04-09 18:40:49 +00:00
print $tableCell ;
2017-06-02 10:27:46 +00:00
print '</td>' ;
2019-11-13 18:35:02 +00:00
$cssonholiday = '' ;
2021-02-23 21:03:23 +00:00
if ( ! $isavailable [ $preselectedday ][ 'morning' ] && ! $isavailable [ $preselectedday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayallday ' ;
} elseif ( ! $isavailable [ $preselectedday ][ 'morning' ]) {
$cssonholiday .= 'onholidaymorning ' ;
} elseif ( ! $isavailable [ $preselectedday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayafternoon ' ;
}
2017-09-19 14:40:55 +00:00
2018-02-09 19:11:32 +00:00
global $daytoparse ;
2019-11-13 18:35:02 +00:00
$tmparray = dol_getdate ( $daytoparse , true ); // detail of current day
2018-02-09 19:11:32 +00:00
2023-11-27 10:39:32 +00:00
$idw = ( $tmparray [ 'wday' ] - ( ! getDolGlobalString ( 'MAIN_START_WEEK' ) ? 0 : 1 ));
2018-02-09 19:11:32 +00:00
global $numstartworkingday , $numendworkingday ;
2019-11-13 18:35:02 +00:00
$cssweekend = '' ;
2021-02-23 21:03:23 +00:00
if ((( $idw + 1 ) < $numstartworkingday ) || (( $idw + 1 ) > $numendworkingday )) { // This is a day is not inside the setup of working days, so we use a week-end css.
2019-11-13 18:35:02 +00:00
$cssweekend = 'weekend' ;
2018-02-09 19:11:32 +00:00
}
2015-04-09 18:40:49 +00:00
2018-02-09 19:11:32 +00:00
// Duration
2019-11-13 18:35:02 +00:00
print '<td class="center duration' . ( $cssonholiday ? ' ' . $cssonholiday : '' ) . ( $cssweekend ? ' ' . $cssweekend : '' ) . '">' ;
2026-04-23 12:57:54 +00:00
$dayWorkLoad = empty ( $projectstatic -> weekWorkLoadPerTask [ $preselectedday ][ $lines [ $i ] -> id ]) ? 0 : ( int ) $projectstatic -> weekWorkLoadPerTask [ $preselectedday ][ $lines [ $i ] -> id ];
2022-12-31 12:44:11 +00:00
if ( ! isset ( $totalforeachday [ $preselectedday ])) {
$totalforeachday [ $preselectedday ] = 0 ;
}
2019-11-13 18:35:02 +00:00
$totalforeachday [ $preselectedday ] += $dayWorkLoad ;
2017-11-16 21:55:04 +00:00
2019-11-13 18:35:02 +00:00
$alreadyspent = '' ;
2021-02-23 21:03:23 +00:00
if ( $dayWorkLoad > 0 ) {
$alreadyspent = convertSecondToTime ( $dayWorkLoad , 'allhourmin' );
}
2015-04-09 18:40:49 +00:00
2017-10-07 11:09:31 +00:00
$idw = 0 ;
2017-09-18 12:18:34 +00:00
2019-11-13 18:35:02 +00:00
$tableCell = '' ;
2025-11-15 22:00:02 +00:00
$tableCell .= '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center width50" disabled id="timespent[' . $inc . '][' . $idw . ']" name="task[' . $lines [ $i ] -> id . '][' . $idw . ']" value="' . $alreadyspent . '"></span>' ;
2019-11-13 18:35:02 +00:00
$tableCell .= '<span class="hideonsmartphone"> + </span>' ;
2015-04-09 18:40:49 +00:00
//$tableCell.=' ';
2019-11-13 18:35:02 +00:00
$tableCell .= $form -> select_duration ( $lines [ $i ] -> id . 'duration' , '' , $disabledtask , 'text' , 0 , 1 );
2015-05-07 09:57:23 +00:00
//$tableCell.=' <input type="submit" class="button"'.($disabledtask?' disabled':'').' value="'.$langs->trans("Add").'">';
2015-04-09 18:40:49 +00:00
print $tableCell ;
2017-09-18 12:18:34 +00:00
2015-03-01 16:45:36 +00:00
print '</td>' ;
2017-10-12 11:03:45 +00:00
// Note
2019-03-14 13:18:44 +00:00
print '<td class="center">' ;
2025-12-04 11:22:44 +00:00
print '<textarea class="padding3" name="' . $lines [ $i ] -> id . 'note" rows="' . ROWS_2 . '" id="' . $lines [ $i ] -> id . 'note"' . ( $disabledtask ? ' disabled="disabled"' : '' ) . '>' ;
2017-06-02 10:27:46 +00:00
print '</textarea>' ;
2015-03-01 16:45:36 +00:00
print '</td>' ;
2017-06-02 10:27:46 +00:00
// Warning
2019-03-14 13:18:44 +00:00
print '<td class="right">' ;
2021-02-23 21:03:23 +00:00
if (( ! $lines [ $i ] -> public ) && $disabledproject ) {
print $form -> textwithpicto ( '' , $langs -> trans ( " UserIsNotContactOfProject " ));
} elseif ( $disabledtask ) {
$titleassigntask = $langs -> trans ( " AssignTaskToMe " );
if ( $fuser -> id != $user -> id ) {
$titleassigntask = $langs -> trans ( " AssignTaskToUser " , '...' );
}
print $form -> textwithpicto ( '' , $langs -> trans ( " TaskIsNotAssignedToUser " , $titleassigntask ));
}
2016-05-04 10:24:15 +00:00
print '</td>' ;
2017-06-02 10:27:46 +00:00
2015-03-01 16:45:36 +00:00
print " </tr> \n " ;
}
$inc ++ ;
$level ++ ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> id > 0 ) {
2017-11-16 21:55:04 +00:00
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
//var_dump($totalforeachday);
2019-10-06 12:41:52 +00:00
$ret = projectLinesPerDay ( $inc , $lines [ $i ] -> id , $fuser , ( $parent == 0 ? $lineswithoutlevel0 : $lines ), $level , $projectsrole , $tasksrole , $mine , $restricteditformytask , $preselectedday , $isavailable , $oldprojectforbreak , $arrayfields , $extrafields );
2017-11-16 21:55:04 +00:00
//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
//var_dump($ret);
2021-02-23 21:03:23 +00:00
foreach ( $ret as $key => $val ) {
2019-11-13 18:35:02 +00:00
$totalforeachday [ $key ] += $val ;
2017-11-16 21:55:04 +00:00
}
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
//var_dump($totalforeachday);
2016-07-08 15:06:12 +00:00
}
2015-03-01 16:45:36 +00:00
$level -- ;
2020-05-21 13:05:19 +00:00
} else {
2015-03-01 16:45:36 +00:00
//$level--;
}
}
2017-11-16 21:55:04 +00:00
return $totalforeachday ;
2015-03-01 16:45:36 +00:00
}
/**
2024-01-13 18:48:20 +00:00
* Output a task line into a perday input mode
2015-03-01 16:45:36 +00:00
*
2024-11-21 21:36:00 +00:00
* @ param int $inc Line output identificator ( start to 0 , then increased by recursive call )
2015-03-18 10:04:50 +00:00
* @ param int $firstdaytoshow First day to show
2024-09-22 22:37:30 +00:00
* @ param ? User $fuser Restrict list to user if defined
2024-08-20 07:46:59 +00:00
* @ param int $parent Id of parent task to show ( 0 to show all )
2016-07-08 10:02:09 +00:00
* @ param Task [] $lines Array of lines ( list of tasks but we will show only if we have a specific role on task )
2015-03-05 10:13:44 +00:00
* @ param int $level Level ( start to 0 , then increased / decrease by recursive call )
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $projectsrole Array of roles user has on project
* @ param array < int , string > $tasksrole Array of roles user has on task
2024-09-22 22:37:30 +00:00
* @ param int < 0 , 1 > $mine Show only task lines I am assigned to
* @ param int < 0 , 2 > $restricteditformytask 0 = No restriction , 1 = Enable add time only if task is assigned to me , 2 = Enable add time only if tasks is assigned to me and hide others
* @ param array < int , array { morning : int < 0 , 1 > , afternoon : int < 0 , 1 > } > $isavailable Array with data that say if user is available for several days for morning and afternoon
2017-11-02 14:33:04 +00:00
* @ param int $oldprojectforbreak Old project id of last project break
2025-01-27 12:52:55 +00:00
* @ param array < string , array < string , int | string >> $arrayfields Array of additional column
2019-10-06 12:41:52 +00:00
* @ param Extrafields $extrafields Object extrafields
2024-09-22 22:37:30 +00:00
* @ return array < int , int > Array with time spent for $fuser for each day of week on tasks in $lines and subtasks
2015-03-01 16:45:36 +00:00
*/
2019-10-06 12:41:52 +00:00
function projectLinesPerWeek ( & $inc , $firstdaytoshow , $fuser , $parent , $lines , & $level , & $projectsrole , & $tasksrole , $mine , $restricteditformytask , & $isavailable , $oldprojectforbreak = 0 , $arrayfields = array (), $extrafields = null )
2015-03-01 16:45:36 +00:00
{
2020-03-23 19:16:51 +00:00
global $conf , $db , $user , $langs ;
2016-07-20 16:02:33 +00:00
global $form , $formother , $projectstatic , $taskstatic , $thirdpartystatic ;
2024-09-22 22:37:30 +00:00
'
@ phan - var - force FormOther $formother
@ phan - var - force Project $projectstatic
@ phan - var - force Task $taskstatic
@ phan - var - force Societe $thirdpartystatic
' ;
2015-03-01 16:45:36 +00:00
2019-11-13 18:35:02 +00:00
$numlines = count ( $lines );
2016-07-08 10:02:09 +00:00
2019-11-13 18:35:02 +00:00
$lastprojectid = 0 ;
$workloadforid = array ();
$totalforeachday = array ();
$lineswithoutlevel0 = array ();
2017-06-02 10:27:46 +00:00
2016-07-08 15:06:12 +00:00
// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
2021-02-23 21:03:23 +00:00
if ( $parent == 0 ) { // Always and only if at first level
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $lines [ $i ] -> fk_task_parent ) {
$lineswithoutlevel0 [] = $lines [ $i ];
}
2017-10-07 11:09:31 +00:00
}
2016-07-08 15:06:12 +00:00
}
2017-10-07 11:09:31 +00:00
//dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
2017-06-02 10:27:46 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak )) {
2023-11-27 10:39:32 +00:00
$oldprojectforbreak = ( ! getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' ) ? 0 : - 1 ); // 0 = start break, -1 = never break
2017-11-02 14:33:04 +00:00
}
2017-10-12 11:03:45 +00:00
2021-06-09 09:03:04 +00:00
$restrictBefore = null ;
2021-06-08 16:13:18 +00:00
2024-06-14 17:39:26 +00:00
if ( getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' )) {
2021-06-09 09:03:04 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2024-06-14 17:39:26 +00:00
$restrictBefore = dol_time_plus_duree ( dol_now (), - 1 * getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' ), 'm' );
2021-06-09 09:03:04 +00:00
}
2021-06-08 16:13:18 +00:00
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $parent == 0 ) {
$level = 0 ;
}
2017-06-02 10:27:46 +00:00
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> fk_task_parent == $parent ) {
2020-10-31 13:32:18 +00:00
$obj = & $lines [ $i ]; // To display extrafields
2019-03-21 13:21:29 +00:00
2015-03-01 16:45:36 +00:00
// If we want all or we have a role on task, we show it
2021-02-23 21:03:23 +00:00
if ( empty ( $mine ) || ! empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2017-10-07 11:09:31 +00:00
//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
2017-06-02 10:27:46 +00:00
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask == 2 && empty ( $tasksrole [ $lines [ $i ] -> id ])) { // we have no role on task and we request to hide such cases
2018-09-16 11:28:37 +00:00
continue ;
}
2018-12-09 23:25:10 +00:00
2017-10-07 11:09:31 +00:00
// Break on a new project
2021-02-23 21:03:23 +00:00
if ( $parent == 0 && $lines [ $i ] -> fk_project != $lastprojectid ) {
2019-11-13 18:35:02 +00:00
$lastprojectid = $lines [ $i ] -> fk_project ;
2017-10-07 11:09:31 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
}
2017-06-02 10:27:46 +00:00
2017-11-16 18:41:31 +00:00
//var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
//var_dump($projectstatic->weekWorkLoadPerTask);
2021-02-23 21:03:23 +00:00
if ( empty ( $workloadforid [ $projectstatic -> id ])) {
2023-04-07 01:08:02 +00:00
$projectstatic -> loadTimeSpent ( $firstdaytoshow , 0 , $fuser -> id ); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
2019-11-13 18:35:02 +00:00
$workloadforid [ $projectstatic -> id ] = 1 ;
2017-10-07 11:09:31 +00:00
}
2017-11-16 18:41:31 +00:00
//var_dump($projectstatic->weekWorkLoadPerTask);
//var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
2017-06-02 10:27:46 +00:00
2019-11-13 18:35:02 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
$projectstatic -> ref = $lines [ $i ] -> projectref ;
$projectstatic -> title = $lines [ $i ] -> projectlabel ;
$projectstatic -> public = $lines [ $i ] -> public ;
$projectstatic -> thirdparty_name = $lines [ $i ] -> thirdparty_name ;
2021-01-26 14:16:06 +00:00
$projectstatic -> status = $lines [ $i ] -> projectstatus ;
2017-08-24 15:59:20 +00:00
2019-11-13 18:35:02 +00:00
$taskstatic -> id = $lines [ $i ] -> id ;
$taskstatic -> ref = ( $lines [ $i ] -> ref ? $lines [ $i ] -> ref : $lines [ $i ] -> id );
$taskstatic -> label = $lines [ $i ] -> label ;
$taskstatic -> date_start = $lines [ $i ] -> date_start ;
$taskstatic -> date_end = $lines [ $i ] -> date_end ;
2017-10-12 11:03:45 +00:00
2019-11-13 18:35:02 +00:00
$thirdpartystatic -> id = $lines [ $i ] -> thirdparty_id ;
$thirdpartystatic -> name = $lines [ $i ] -> thirdparty_name ;
$thirdpartystatic -> email = $lines [ $i ] -> thirdparty_email ;
2017-10-12 11:03:45 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak ) || ( $oldprojectforbreak != - 1 && $oldprojectforbreak != $projectstatic -> id )) {
2020-10-31 13:32:18 +00:00
$addcolspan = 0 ;
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
$addcolspan ++ ;
}
if ( ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
$addcolspan ++ ;
}
foreach ( $arrayfields as $key => $val ) {
if ( $val [ 'checked' ] && substr ( $key , 0 , 5 ) == 'efpt.' ) {
$addcolspan ++ ;
}
2020-10-31 13:32:18 +00:00
}
2019-03-21 13:21:29 +00:00
2020-03-24 12:06:59 +00:00
print '<tr class="oddeven trforbreak nobold">' . " \n " ;
2019-11-13 18:35:02 +00:00
print '<td colspan="' . ( 11 + $addcolspan ) . '">' ;
2019-01-27 10:55:16 +00:00
print $projectstatic -> getNomUrl ( 1 , '' , 0 , '<strong>' . $langs -> transnoentitiesnoconv ( " YourRole " ) . ':</strong> ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print ' - ' . $thirdpartystatic -> getNomUrl ( 1 );
}
if ( $projectstatic -> title ) {
2017-10-12 11:03:45 +00:00
print ' - ' ;
2020-01-07 13:25:58 +00:00
print '<span class="secondary">' . $projectstatic -> title . '</span>' ;
2017-10-12 11:03:45 +00:00
}
2019-03-21 13:21:29 +00:00
2020-10-31 13:32:18 +00:00
/* $colspan = 5 + ( empty ( $conf -> global -> PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT ) ? 0 : 2 );
2019-03-21 13:21:29 +00:00
print '<table class="">' ;
print '<tr class="liste_titre">' ;
// PROJECT fields
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.fk_opp_status' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.fk_opp_status' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.fk_opp_status' , " " , $param , '' , $sortfield , $sortorder , 'center ' );
if ( ! empty ( $arrayfields [ 'p.opp_amount' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.opp_amount' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.opp_amount' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.opp_percent' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.opp_percent' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.opp_percent' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.budget_amount' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.budget_amount' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.budget_amount' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
if ( ! empty ( $arrayfields [ 'p.usage_bill_time' ][ 'checked' ])) print_liste_field_titre ( $arrayfields [ 'p.usage_bill_time' ][ 'label' ], $_SERVER [ " PHP_SELF " ], 'p.usage_bill_time' , " " , $param , '' , $sortfield , $sortorder , 'right ' );
2021-02-23 21:03:23 +00:00
$extrafieldsobjectkey = 'projet' ;
$extrafieldsobjectprefix = 'efp.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_title.tpl.php' ;
print '</tr>' ;
print '<tr>' ;
// PROJECT fields
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.fk_opp_status' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
$code = dol_getIdFromCode ( $db , $lines [ $i ] -> fk_opp_status , 'c_lead_status' , 'rowid' , 'code' );
if ( $code ) print $langs -> trans ( " OppStatus " . $code );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.opp_amount' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> opp_amount , 0 , $langs , 1 , 0 , - 1 , $conf -> currency );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.opp_percent' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> opp_percent , 0 , $langs , 1 , 0 ) . ' %' ;
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.budget_amount' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print price ( $lines [ $i ] -> budget_amount , 0 , $langs , 1 , 0 , 0 , $conf -> currency );
print " </td> \n " ;
}
2022-08-31 20:14:20 +00:00
if ( ! empty ( $arrayfields [ 'p.usage_bill_time' ][ 'checked' ]))
2021-02-23 21:03:23 +00:00
{
print '<td class="nowrap">' ;
print yn ( $lines [ $i ] -> usage_bill_time );
print " </td> \n " ;
}
$extrafieldsobjectkey = 'projet' ;
$extrafieldsobjectprefix = 'efp.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php' ;
print '</tr>' ;
print '</table>' ;
2019-03-31 20:06:41 +00:00
*/
2019-03-21 13:21:29 +00:00
2017-10-12 11:03:45 +00:00
print '</td>' ;
print '</tr>' ;
}
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak != - 1 ) {
$oldprojectforbreak = $projectstatic -> id ;
}
2017-10-12 11:03:45 +00:00
2019-11-21 16:05:06 +00:00
print '<tr class="oddeven" data-taskid="' . $lines [ $i ] -> id . '">' . " \n " ;
2017-06-02 10:27:46 +00:00
// User
2017-07-28 21:32:55 +00:00
/*
2017-06-02 10:27:46 +00:00
print '<td class="nowrap">' ;
print $fuser -> getNomUrl ( 1 , 'withproject' , 'time' );
print '</td>' ;
2017-07-28 21:32:55 +00:00
*/
2015-03-01 16:45:36 +00:00
2017-08-24 15:59:20 +00:00
// Project
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' )) {
2020-10-31 13:32:18 +00:00
print '<td class="nowrap">' ;
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak == - 1 ) {
print $projectstatic -> getNomUrl ( 1 , '' , 0 , $langs -> transnoentitiesnoconv ( " YourRole " ) . ': ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
}
2020-10-31 13:32:18 +00:00
print " </td> " ;
2019-03-31 20:06:41 +00:00
}
2017-08-24 15:59:20 +00:00
2017-10-09 16:18:34 +00:00
// Thirdparty
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' )) {
2020-10-31 13:32:18 +00:00
print '<td class="tdoverflowmax100">' ;
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print $thirdpartystatic -> getNomUrl ( 1 , 'project' );
}
2020-10-31 13:32:18 +00:00
print '</td>' ;
2019-03-31 20:06:41 +00:00
}
2017-08-24 15:59:20 +00:00
2015-03-01 16:45:36 +00:00
// Ref
2026-05-05 11:50:20 +00:00
print '<td>' ;
2023-11-20 10:41:02 +00:00
print '<!-- Task id = ' . $lines [ $i ] -> id . ' (projectlinesperweek) -->' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print '<div class="marginleftonly">' ;
}
2015-03-18 10:04:50 +00:00
print $taskstatic -> getNomUrl ( 1 , 'withproject' , 'time' );
2015-03-01 16:45:36 +00:00
// Label task
2017-10-12 11:03:45 +00:00
print '<br>' ;
2026-05-05 11:50:20 +00:00
print '<div class="opacitymedium tdoverflowmax400 small" title="' . dol_escape_htmltag ( $taskstatic -> label ) . '">' . dol_escape_htmltag ( $taskstatic -> label ) . '</div>' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print " </div> " ;
}
2015-03-01 16:45:36 +00:00
print " </td> \n " ;
2019-03-21 13:21:29 +00:00
// TASK extrafields
2020-10-31 13:32:18 +00:00
$extrafieldsobjectkey = 'projet_task' ;
$extrafieldsobjectprefix = 'efpt.' ;
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php' ;
// Planned Workload
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
2020-10-31 13:32:18 +00:00
print '<td class="leftborder plannedworkload right">' ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> planned_workload ) {
print convertSecondToTime ( $lines [ $i ] -> planned_workload , 'allhourmin' );
} else {
print '--:--' ;
}
2020-10-31 13:32:18 +00:00
print '</td>' ;
}
2021-02-23 21:03:23 +00:00
if ( ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
2020-10-31 13:32:18 +00:00
// Progress declared %
print '<td class="right">' ;
print $formother -> select_percent ( $lines [ $i ] -> progress , $lines [ $i ] -> id . 'progress' );
print '</td>' ;
}
2014-08-07 23:19:03 +00:00
2021-04-10 11:29:24 +00:00
if ( ! empty ( $arrayfields [ 'timeconsumed' ][ 'checked' ])) {
// Time spent by everybody
print '<td class="right">' ;
2023-06-29 13:54:09 +00:00
// $lines[$i]->duration_effective is a denormalised field = summ of time spent by everybody for task. What we need is time consumed by user
if ( $lines [ $i ] -> duration_effective ) {
2023-11-20 10:41:02 +00:00
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . (( int ) $lines [ $i ] -> id ) . '">' ;
2023-06-29 13:54:09 +00:00
print convertSecondToTime ( $lines [ $i ] -> duration_effective , 'allhourmin' );
2021-04-10 11:29:24 +00:00
print '</a>' ;
} else {
print '--:--' ;
}
print " </td> \n " ;
2015-03-05 12:48:57 +00:00
2021-04-10 11:29:24 +00:00
// Time spent by user
print '<td class="right">' ;
$tmptimespent = $taskstatic -> getSummaryOfTimeSpent ( $fuser -> id );
if ( $tmptimespent [ 'total_duration' ]) {
2023-11-20 10:41:02 +00:00
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . (( int ) $lines [ $i ] -> id ) . '&search_user=' . (( int ) $fuser -> id ) . '">' ;
2021-04-10 11:29:24 +00:00
print convertSecondToTime ( $tmptimespent [ 'total_duration' ], 'allhourmin' );
2023-11-20 10:41:02 +00:00
print '</a>' ;
2021-04-10 11:29:24 +00:00
} else {
print '--:--' ;
}
print " </td> \n " ;
2021-02-23 21:03:23 +00:00
}
2014-08-07 23:19:03 +00:00
2021-03-01 19:37:16 +00:00
$disabledproject = 1 ;
$disabledtask = 1 ;
2014-08-07 09:48:19 +00:00
//print "x".$lines[$i]->fk_project;
//var_dump($lines[$i]);
//var_dump($projectsrole[$lines[$i]->fk_project]);
// If at least one role for project
2023-10-15 13:32:35 +00:00
if ( $lines [ $i ] -> public || ! empty ( $projectsrole [ $lines [ $i ] -> fk_project ]) || $user -> hasRight ( 'projet' , 'all' , 'creer' )) {
2019-11-13 18:35:02 +00:00
$disabledproject = 0 ;
$disabledtask = 0 ;
2014-08-07 09:48:19 +00:00
}
// If $restricteditformytask is on and I have no role on task, i disable edit
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask && empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2019-11-13 18:35:02 +00:00
$disabledtask = 1 ;
2014-08-07 09:48:19 +00:00
}
2014-08-07 23:19:03 +00:00
2015-03-18 10:04:50 +00:00
//var_dump($projectstatic->weekWorkLoadPerTask);
2017-06-02 10:27:46 +00:00
2015-03-03 23:53:35 +00:00
// Fields to show current time
2021-03-01 19:37:16 +00:00
$tableCell = '' ;
$modeinput = 'hours' ;
2024-06-25 11:49:55 +00:00
$j = 0 ;
2021-02-23 21:03:23 +00:00
for ( $idw = 0 ; $idw < 7 ; $idw ++ ) {
2024-06-25 11:49:55 +00:00
$j ++ ;
2019-11-13 18:35:02 +00:00
$tmpday = dol_time_plus_duree ( $firstdaytoshow , $idw , 'd' );
2023-12-04 11:05:28 +00:00
if ( ! isset ( $totalforeachday [ $tmpday ])) {
$totalforeachday [ $tmpday ] = 0 ;
}
2019-11-13 18:35:02 +00:00
$cssonholiday = '' ;
2021-02-23 21:03:23 +00:00
if ( ! $isavailable [ $tmpday ][ 'morning' ] && ! $isavailable [ $tmpday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayallday ' ;
} elseif ( ! $isavailable [ $tmpday ][ 'morning' ]) {
$cssonholiday .= 'onholidaymorning ' ;
} elseif ( ! $isavailable [ $tmpday ][ 'afternoon' ]) {
$cssonholiday .= 'onholidayafternoon ' ;
}
2017-09-19 14:40:55 +00:00
2019-11-13 18:35:02 +00:00
$tmparray = dol_getdate ( $tmpday );
2026-04-23 12:57:54 +00:00
$dayWorkLoad = ( ! empty ( $projectstatic -> weekWorkLoadPerTask [ $tmpday ][ $lines [ $i ] -> id ]) ? ( int ) $projectstatic -> weekWorkLoadPerTask [ $tmpday ][ $lines [ $i ] -> id ] : 0 );
2019-11-13 18:35:02 +00:00
$totalforeachday [ $tmpday ] += $dayWorkLoad ;
2017-11-16 18:41:31 +00:00
2019-11-13 18:35:02 +00:00
$alreadyspent = '' ;
2021-02-23 21:03:23 +00:00
if ( $dayWorkLoad > 0 ) {
$alreadyspent = convertSecondToTime ( $dayWorkLoad , 'allhourmin' );
}
2022-10-28 13:48:46 +00:00
$alttitle = $langs -> trans ( " AddHereTimeSpentForDay " , ! empty ( $tmparray [ 'day' ]) ? $tmparray [ 'day' ] : 0 , $tmparray [ 'mon' ]);
2017-10-07 11:09:31 +00:00
2018-02-09 19:11:32 +00:00
global $numstartworkingday , $numendworkingday ;
2019-11-13 18:35:02 +00:00
$cssweekend = '' ;
2021-02-23 21:03:23 +00:00
if (( $idw + 1 < $numstartworkingday ) || ( $idw + 1 > $numendworkingday )) { // This is a day is not inside the setup of working days, so we use a week-end css.
2019-11-13 18:35:02 +00:00
$cssweekend = 'weekend' ;
2018-02-09 19:11:32 +00:00
}
2021-06-09 09:03:04 +00:00
$disabledtaskday = $disabledtask ;
2021-06-08 16:13:18 +00:00
2021-06-09 09:03:04 +00:00
if ( ! $disabledtask && $restrictBefore && $tmpday < $restrictBefore ) {
$disabledtaskday = 1 ;
}
2021-06-08 16:13:18 +00:00
2024-06-25 11:49:55 +00:00
$tableCell = '<td class="center hide' . $idw . ( $cssonholiday ? ' ' . $cssonholiday : '' ) . ( $cssweekend ? ' ' . $cssweekend : '' ) . ( $j <= 1 ? ' borderleft' : '' ) . '">' ;
2020-11-05 18:09:58 +00:00
//$tableCell .= 'idw='.$idw.' '.$conf->global->MAIN_START_WEEK.' '.$numstartworkingday.'-'.$numendworkingday;
2019-11-13 18:35:02 +00:00
$placeholder = '' ;
2021-02-23 21:03:23 +00:00
if ( $alreadyspent ) {
2025-11-15 22:00:02 +00:00
$tableCell .= '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd width50" disabled id="timespent[' . $inc . '][' . $idw . ']" name="task[' . $lines [ $i ] -> id . '][' . $idw . ']" value="' . $alreadyspent . '"></span>' ;
2017-10-07 11:09:31 +00:00
//$placeholder=' placeholder="00:00"';
2021-02-23 21:03:23 +00:00
//$tableCell.='+';
2017-10-07 11:09:31 +00:00
}
2023-12-30 18:50:41 +00:00
$tableCell .= '<input type="text" alt="' . ( $disabledtaskday ? '' : $alttitle ) . '" title="' . ( $disabledtaskday ? '' : $alttitle ) . '" ' . ( $disabledtaskday ? 'disabled' : $placeholder ) . ' class="center smallpadd width40" id="timeadded[' . $inc . '][' . $idw . ']" name="task[' . $lines [ $i ] -> id . '][' . $idw . ']" value="" cols="2" maxlength="5"' ;
2019-11-13 18:35:02 +00:00
$tableCell .= ' onkeypress="return regexEvent(this,event,\'timeChar\')"' ;
2021-02-23 21:03:23 +00:00
$tableCell .= ' onkeyup="updateTotal(' . $idw . ',\'' . $modeinput . '\')"' ;
$tableCell .= ' onblur="regexEvent(this,event,\'' . $modeinput . '\'); updateTotal(' . $idw . ',\'' . $modeinput . '\')" />' ;
$tableCell .= '</td>' ;
2017-10-07 11:09:31 +00:00
print $tableCell ;
}
// Warning
2019-03-14 13:18:44 +00:00
print '<td class="right">' ;
2021-02-23 21:03:23 +00:00
if (( ! $lines [ $i ] -> public ) && $disabledproject ) {
print $form -> textwithpicto ( '' , $langs -> trans ( " UserIsNotContactOfProject " ));
} elseif ( $disabledtask ) {
$titleassigntask = $langs -> trans ( " AssignTaskToMe " );
if ( $fuser -> id != $user -> id ) {
$titleassigntask = $langs -> trans ( " AssignTaskToUser " , '...' );
}
print $form -> textwithpicto ( '' , $langs -> trans ( " TaskIsNotAssignedToUser " , $titleassigntask ));
}
2015-04-09 18:40:49 +00:00
print '</td>' ;
2017-10-07 11:09:31 +00:00
print " </tr> \n " ;
2013-04-12 09:09:53 +00:00
}
2016-07-08 15:06:12 +00:00
// Call to show task with a lower level (task under the current task)
2013-04-12 09:09:53 +00:00
$inc ++ ;
$level ++ ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> id > 0 ) {
2017-11-16 21:55:04 +00:00
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
//var_dump($totalforeachday);
2019-10-06 12:41:52 +00:00
$ret = projectLinesPerWeek ( $inc , $firstdaytoshow , $fuser , $lines [ $i ] -> id , ( $parent == 0 ? $lineswithoutlevel0 : $lines ), $level , $projectsrole , $tasksrole , $mine , $restricteditformytask , $isavailable , $oldprojectforbreak , $arrayfields , $extrafields );
2017-11-16 21:55:04 +00:00
//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
//var_dump($ret);
2021-02-23 21:03:23 +00:00
foreach ( $ret as $key => $val ) {
2019-11-13 18:35:02 +00:00
$totalforeachday [ $key ] += $val ;
2017-11-16 21:55:04 +00:00
}
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
//var_dump($totalforeachday);
2016-07-08 15:06:12 +00:00
}
2013-04-12 09:09:53 +00:00
$level -- ;
2020-05-21 13:05:19 +00:00
} else {
2013-04-12 09:09:53 +00:00
//$level--;
}
}
2017-11-16 21:55:04 +00:00
return $totalforeachday ;
2012-02-15 22:08:20 +00:00
}
2019-11-21 16:05:06 +00:00
/**
2024-01-13 18:48:20 +00:00
* Output a task line into a perday input mode
2019-11-21 16:05:06 +00:00
*
2024-11-21 21:36:00 +00:00
* @ param int $inc Line output identificator ( start to 0 , then increased by recursive call )
2019-11-21 16:05:06 +00:00
* @ param int $firstdaytoshow First day to show
* @ param User | null $fuser Restrict list to user if defined
2024-08-20 07:46:59 +00:00
* @ param int $parent Id of parent task to show ( 0 to show all )
2019-11-21 16:05:06 +00:00
* @ param Task [] $lines Array of lines ( list of tasks but we will show only if we have a specific role on task )
* @ param int $level Level ( start to 0 , then increased / decrease by recursive call )
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $projectsrole Array of roles user has on project
* @ param array < int , string > $tasksrole Array of roles user has on task
2024-09-22 22:37:30 +00:00
* @ param int < 0 , 1 > $mine Show only task lines I am assigned to
* @ param int < 0 , 1 > $restricteditformytask 0 = No restriction , 1 = Enable add time only if task is a task i am affected to
* @ param array < int , array { morning : int < 0 , 1 > , afternoon : int < 0 , 1 > } > $isavailable Array with data that say if user is available for several days for morning and afternoon
2019-11-21 16:05:06 +00:00
* @ param int $oldprojectforbreak Old project id of last project break
2025-02-10 20:20:09 +00:00
* @ param string [] $TWeek Array of week numbers ( '02' , ...
2025-01-27 12:52:55 +00:00
* @ param array < string , array < string , int | string >> $arrayfields Array of additional column
2024-06-14 17:39:26 +00:00
* @ param Extrafields $extrafields Object extrafields
2024-09-22 22:37:30 +00:00
* @ return array < string , int > Array with time spent for $fuser for each day of week on tasks in $lines and subtasks ( index is string , month is '01' , ... )
2019-11-21 16:05:06 +00:00
*/
2024-06-14 17:39:26 +00:00
function projectLinesPerMonth ( & $inc , $firstdaytoshow , $fuser , $parent , $lines , & $level , & $projectsrole , & $tasksrole , $mine , $restricteditformytask , & $isavailable , $oldprojectforbreak = 0 , $TWeek = array (), $arrayfields = array (), $extrafields = null )
2019-11-21 16:05:06 +00:00
{
2020-03-23 19:16:51 +00:00
global $conf , $db , $user , $langs ;
2019-11-21 16:05:06 +00:00
global $form , $formother , $projectstatic , $taskstatic , $thirdpartystatic ;
2024-09-22 22:37:30 +00:00
'
@ phan - var - force FormOther $formother
@ phan - var - force Project $projectstatic
@ phan - var - force Task $taskstatic
@ phan - var - force Societe $thirdpartystatic
' ;
2019-11-21 16:05:06 +00:00
2020-02-21 16:53:37 +00:00
$numlines = count ( $lines );
2019-11-21 16:05:06 +00:00
2020-02-21 16:53:37 +00:00
$lastprojectid = 0 ;
$workloadforid = array ();
$totalforeachweek = array ();
$lineswithoutlevel0 = array ();
2019-11-21 16:05:06 +00:00
// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
2021-02-23 21:03:23 +00:00
if ( $parent == 0 ) { // Always and only if at first level
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $lines [ $i ] -> fk_task_parent ) {
$lineswithoutlevel0 [] = $lines [ $i ];
}
2019-11-21 16:05:06 +00:00
}
}
//dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak )) {
2023-11-27 10:39:32 +00:00
$oldprojectforbreak = ( ! getDolGlobalString ( 'PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT' ) ? 0 : - 1 ); // 0 = start break, -1 = never break
2019-11-21 16:05:06 +00:00
}
2021-06-09 09:03:04 +00:00
$restrictBefore = null ;
2021-06-08 16:13:18 +00:00
2024-06-14 17:39:26 +00:00
if ( getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' )) {
2021-06-09 09:03:04 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2024-06-14 17:39:26 +00:00
$restrictBefore = dol_time_plus_duree ( dol_now (), - 1 * getDolGlobalInt ( 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS' ), 'm' );
2021-06-09 09:03:04 +00:00
}
2021-06-08 16:13:18 +00:00
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
if ( $parent == 0 ) {
$level = 0 ;
}
2019-11-21 16:05:06 +00:00
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> fk_task_parent == $parent ) {
2019-11-21 16:05:06 +00:00
// If we want all or we have a role on task, we show it
2021-02-23 21:03:23 +00:00
if ( empty ( $mine ) || ! empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2019-11-21 16:05:06 +00:00
//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
2024-01-19 10:09:11 +00:00
if ( $restricteditformytask == 2 && empty ( $tasksrole [ $lines [ $i ] -> id ])) { // we have no role on task and we request to hide such cases
continue ;
}
2019-11-21 16:05:06 +00:00
// Break on a new project
2021-02-23 21:03:23 +00:00
if ( $parent == 0 && $lines [ $i ] -> fk_project != $lastprojectid ) {
2020-02-21 16:53:37 +00:00
$lastprojectid = $lines [ $i ] -> fk_project ;
2019-11-21 16:05:06 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
}
//var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
//var_dump($projectstatic->weekWorkLoadPerTask);
2021-02-23 21:03:23 +00:00
if ( empty ( $workloadforid [ $projectstatic -> id ])) {
2023-04-07 01:08:02 +00:00
$projectstatic -> loadTimeSpentMonth ( $firstdaytoshow , 0 , $fuser -> id ); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
2020-02-21 16:53:37 +00:00
$workloadforid [ $projectstatic -> id ] = 1 ;
2019-11-21 16:05:06 +00:00
}
//var_dump($projectstatic->weekWorkLoadPerTask);
//var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
2020-02-21 16:53:37 +00:00
$projectstatic -> id = $lines [ $i ] -> fk_project ;
$projectstatic -> ref = $lines [ $i ] -> projectref ;
$projectstatic -> title = $lines [ $i ] -> projectlabel ;
$projectstatic -> public = $lines [ $i ] -> public ;
$projectstatic -> thirdparty_name = $lines [ $i ] -> thirdparty_name ;
2021-01-18 11:07:40 +00:00
$projectstatic -> status = $lines [ $i ] -> projectstatus ;
2019-11-21 16:05:06 +00:00
2020-02-21 16:53:37 +00:00
$taskstatic -> id = $lines [ $i ] -> id ;
$taskstatic -> ref = ( $lines [ $i ] -> ref ? $lines [ $i ] -> ref : $lines [ $i ] -> id );
$taskstatic -> label = $lines [ $i ] -> label ;
$taskstatic -> date_start = $lines [ $i ] -> date_start ;
$taskstatic -> date_end = $lines [ $i ] -> date_end ;
2019-11-21 16:05:06 +00:00
2020-02-21 16:53:37 +00:00
$thirdpartystatic -> id = $lines [ $i ] -> thirdparty_id ;
$thirdpartystatic -> name = $lines [ $i ] -> thirdparty_name ;
$thirdpartystatic -> email = $lines [ $i ] -> thirdparty_email ;
2019-11-21 16:05:06 +00:00
2021-02-23 21:03:23 +00:00
if ( empty ( $oldprojectforbreak ) || ( $oldprojectforbreak != - 1 && $oldprojectforbreak != $projectstatic -> id )) {
2020-03-24 12:06:59 +00:00
print '<tr class="oddeven trforbreak nobold">' . " \n " ;
2020-02-21 16:53:37 +00:00
print '<td colspan="' . ( 6 + count ( $TWeek )) . '">' ;
2020-01-31 10:26:33 +00:00
print $projectstatic -> getNomUrl ( 1 , '' , 0 , '<strong>' . $langs -> transnoentitiesnoconv ( " YourRole " ) . ':</strong> ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
2021-02-23 21:03:23 +00:00
if ( $thirdpartystatic -> id > 0 ) {
print ' - ' . $thirdpartystatic -> getNomUrl ( 1 );
}
if ( $projectstatic -> title ) {
2019-11-21 16:05:06 +00:00
print ' - ' ;
2020-02-02 19:21:16 +00:00
print '<span class="secondary">' . $projectstatic -> title . '</span>' ;
2019-11-21 16:05:06 +00:00
}
print '</td>' ;
print '</tr>' ;
}
2021-02-23 21:03:23 +00:00
if ( $oldprojectforbreak != - 1 ) {
$oldprojectforbreak = $projectstatic -> id ;
}
2019-11-21 16:05:06 +00:00
print '<tr class="oddeven" data-taskid="' . $lines [ $i ] -> id . '">' . " \n " ;
// User
/*
print '<td class="nowrap">' ;
print $fuser -> getNomUrl ( 1 , 'withproject' , 'time' );
print '</td>' ;
*/
// Project
/* print '<td class="nowrap">' ;
if ( $oldprojectforbreak == - 1 ) print $projectstatic -> getNomUrl ( 1 , '' , 0 , $langs -> transnoentitiesnoconv ( " YourRole " ) . ': ' . $projectsrole [ $lines [ $i ] -> fk_project ]);
print " </td> " ; */
// Thirdparty
/* print '<td class="tdoverflowmax100">' ;
if ( $thirdpartystatic -> id > 0 ) print $thirdpartystatic -> getNomUrl ( 1 , 'project' );
print '</td>' ; */
// Ref
print '<td class="nowrap">' ;
2023-11-20 10:41:02 +00:00
print '<!-- Task id = ' . $lines [ $i ] -> id . ' (projectlinespermonth) -->' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print '<div class="marginleftonly">' ;
}
2019-11-21 16:05:06 +00:00
print $taskstatic -> getNomUrl ( 1 , 'withproject' , 'time' );
// Label task
print '<br>' ;
2026-05-05 11:50:20 +00:00
print '<div class="opacitymedium tdoverflowmax400 small" title="' . dol_escape_htmltag ( $taskstatic -> label ) . '">' . dol_escape_htmltag ( $taskstatic -> label ) . '</div>' ;
2021-02-23 21:03:23 +00:00
for ( $k = 0 ; $k < $level ; $k ++ ) {
print " </div> " ;
}
2019-11-21 16:05:06 +00:00
print " </td> \n " ;
// Planned Workload
2024-06-14 17:39:26 +00:00
if ( ! empty ( $arrayfields [ 't.planned_workload' ][ 'checked' ])) {
print '<td class="leftborder plannedworkload right">' ;
if ( $lines [ $i ] -> planned_workload ) {
print convertSecondToTime ( $lines [ $i ] -> planned_workload , 'allhourmin' );
} else {
print '--:--' ;
}
print '</td>' ;
2021-02-23 21:03:23 +00:00
}
2019-11-21 16:05:06 +00:00
// Progress declared %
2024-06-14 17:39:26 +00:00
if ( ! empty ( $arrayfields [ 't.progress' ][ 'checked' ])) {
print '<td class="right">' ;
print $formother -> select_percent ( $lines [ $i ] -> progress , $lines [ $i ] -> id . 'progress' );
print '</td>' ;
}
2019-11-21 16:05:06 +00:00
// Time spent by everybody
2024-06-14 17:39:26 +00:00
if ( ! empty ( $arrayfields [ 'timeconsumed' ][ 'checked' ])) {
print '<td class="right">' ;
// $lines[$i]->duration_effective is a denormalised field = summ of time spent by everybody for task. What we need is time consumed by user
if ( $lines [ $i ] -> duration_effective ) {
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . $lines [ $i ] -> id . '">' ;
print convertSecondToTime ( $lines [ $i ] -> duration_effective , 'allhourmin' );
print '</a>' ;
} else {
print '--:--' ;
}
print " </td> \n " ;
2019-11-21 16:05:06 +00:00
2024-06-14 17:39:26 +00:00
// Time spent by user
print '<td class="right">' ;
$tmptimespent = $taskstatic -> getSummaryOfTimeSpent ( $fuser -> id );
if ( $tmptimespent [ 'total_duration' ]) {
print convertSecondToTime ( $tmptimespent [ 'total_duration' ], 'allhourmin' );
} else {
print '--:--' ;
}
print " </td> \n " ;
2021-02-23 21:03:23 +00:00
}
2019-11-21 16:05:06 +00:00
2021-03-01 19:37:16 +00:00
$disabledproject = 1 ;
$disabledtask = 1 ;
2019-11-21 16:05:06 +00:00
//print "x".$lines[$i]->fk_project;
//var_dump($lines[$i]);
//var_dump($projectsrole[$lines[$i]->fk_project]);
// If at least one role for project
2023-10-15 13:32:35 +00:00
if ( $lines [ $i ] -> public || ! empty ( $projectsrole [ $lines [ $i ] -> fk_project ]) || $user -> hasRight ( 'projet' , 'all' , 'creer' )) {
2020-02-21 16:53:37 +00:00
$disabledproject = 0 ;
$disabledtask = 0 ;
2019-11-21 16:05:06 +00:00
}
// If $restricteditformytask is on and I have no role on task, i disable edit
2021-02-23 21:03:23 +00:00
if ( $restricteditformytask && empty ( $tasksrole [ $lines [ $i ] -> id ])) {
2020-02-21 16:53:37 +00:00
$disabledtask = 1 ;
2019-11-21 16:05:06 +00:00
}
//var_dump($projectstatic->weekWorkLoadPerTask);
//TODO
// Fields to show current time
2021-03-01 19:37:16 +00:00
$tableCell = '' ;
$modeinput = 'hours' ;
2024-08-13 18:39:40 +00:00
$TFirstDay = getFirstDayOfEachWeek ( $TWeek , ( int ) date ( 'Y' , $firstdaytoshow ));
2019-11-21 16:05:06 +00:00
$TFirstDay [ reset ( $TWeek )] = 1 ;
2021-06-08 16:13:18 +00:00
2021-06-09 09:03:04 +00:00
$firstdaytoshowarray = dol_getdate ( $firstdaytoshow );
$year = $firstdaytoshowarray [ 'year' ];
$month = $firstdaytoshowarray [ 'mon' ];
2024-06-25 11:49:55 +00:00
$j = 0 ;
2021-06-09 09:03:04 +00:00
foreach ( $TWeek as $weekIndex => $weekNb ) {
2024-06-25 11:49:55 +00:00
$j ++ ;
2026-04-23 12:57:54 +00:00
$weekWorkLoad = ! empty ( $projectstatic -> monthWorkLoadPerTask [ $weekNb ][ $lines [ $i ] -> id ]) ? ( int ) $projectstatic -> monthWorkLoadPerTask [ $weekNb ][ $lines [ $i ] -> id ] : 0 ;
2023-12-04 11:05:28 +00:00
if ( ! isset ( $totalforeachweek [ $weekNb ])) {
$totalforeachweek [ $weekNb ] = 0 ;
}
2020-02-21 16:53:37 +00:00
$totalforeachweek [ $weekNb ] += $weekWorkLoad ;
2019-11-21 16:05:06 +00:00
2020-02-21 16:53:37 +00:00
$alreadyspent = '' ;
2021-02-23 21:03:23 +00:00
if ( $weekWorkLoad > 0 ) {
$alreadyspent = convertSecondToTime ( $weekWorkLoad , 'allhourmin' );
}
2020-02-21 16:53:37 +00:00
$alttitle = $langs -> trans ( " AddHereTimeSpentForWeek " , $weekNb );
2019-11-21 16:05:06 +00:00
2021-06-09 09:03:04 +00:00
$disabledtaskweek = $disabledtask ;
$firstdayofweek = dol_mktime ( 0 , 0 , 0 , $month , $TFirstDay [ $weekIndex ], $year );
2021-06-08 16:13:18 +00:00
2021-06-09 09:03:04 +00:00
if ( ! $disabledtask && $restrictBefore && $firstdayofweek < $restrictBefore ) {
$disabledtaskweek = 1 ;
}
2019-11-21 16:05:06 +00:00
2024-06-25 11:49:55 +00:00
$tableCell = '<td class="center hide' . ( $j <= 1 ? ' borderleft' : '' ) . '">' ;
2020-02-21 16:53:37 +00:00
$placeholder = '' ;
2021-02-23 21:03:23 +00:00
if ( $alreadyspent ) {
2025-11-15 22:00:02 +00:00
$tableCell .= '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd width50" disabled id="timespent[' . $inc . '][' . (( int ) $weekNb ) . ']" name="task[' . $lines [ $i ] -> id . '][' . $weekNb . ']" value="' . $alreadyspent . '"></span>' ;
2019-11-21 16:05:06 +00:00
//$placeholder=' placeholder="00:00"';
//$tableCell.='+';
}
2023-12-30 18:50:41 +00:00
$tableCell .= '<input type="text" alt="' . ( $disabledtaskweek ? '' : $alttitle ) . '" title="' . ( $disabledtaskweek ? '' : $alttitle ) . '" ' . ( $disabledtaskweek ? 'disabled' : $placeholder ) . ' class="center smallpadd width40" id="timeadded[' . $inc . '][' . (( int ) $weekNb ) . ']" name="task[' . $lines [ $i ] -> id . '][' . ( $TFirstDay [ $weekNb ] - 1 ) . ']" value="" cols="2" maxlength="5"' ;
2020-02-21 16:53:37 +00:00
$tableCell .= ' onkeypress="return regexEvent(this,event,\'timeChar\')"' ;
$tableCell .= ' onkeyup="updateTotal(' . $weekNb . ',\'' . $modeinput . '\')"' ;
$tableCell .= ' onblur="regexEvent(this,event,\'' . $modeinput . '\'); updateTotal(' . $weekNb . ',\'' . $modeinput . '\')" />' ;
$tableCell .= '</td>' ;
2019-11-21 16:05:06 +00:00
print $tableCell ;
}
// Warning
2020-02-02 19:21:16 +00:00
print '<td class="right">' ;
2021-02-23 21:03:23 +00:00
if (( ! $lines [ $i ] -> public ) && $disabledproject ) {
print $form -> textwithpicto ( '' , $langs -> trans ( " UserIsNotContactOfProject " ));
} elseif ( $disabledtask ) {
2019-11-21 16:05:06 +00:00
$titleassigntask = $langs -> trans ( " AssignTaskToMe " );
2021-02-23 21:03:23 +00:00
if ( $fuser -> id != $user -> id ) {
$titleassigntask = $langs -> trans ( " AssignTaskToUser " , '...' );
}
2019-11-21 16:05:06 +00:00
2020-01-31 10:26:33 +00:00
print $form -> textwithpicto ( '' , $langs -> trans ( " TaskIsNotAssignedToUser " , $titleassigntask ));
2019-11-21 16:05:06 +00:00
}
print '</td>' ;
print " </tr> \n " ;
}
// Call to show task with a lower level (task under the current task)
$inc ++ ;
$level ++ ;
2021-02-23 21:03:23 +00:00
if ( $lines [ $i ] -> id > 0 ) {
2019-11-21 16:05:06 +00:00
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
//var_dump($totalforeachday);
2026-04-17 15:39:17 +00:00
$ret = projectLinesPerMonth ( $inc , $firstdaytoshow , $fuser , $lines [ $i ] -> id , ( $parent == 0 ? $lineswithoutlevel0 : $lines ), $level , $projectsrole , $tasksrole , $mine , $restricteditformytask , $isavailable , $oldprojectforbreak , $TWeek , $arrayfields );
2019-11-21 16:05:06 +00:00
//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
//var_dump($ret);
2021-02-23 21:03:23 +00:00
foreach ( $ret as $key => $val ) {
2020-02-21 16:53:37 +00:00
$totalforeachweek [ $key ] += $val ;
2019-11-21 16:05:06 +00:00
}
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
//var_dump($totalforeachday);
}
$level -- ;
2020-05-21 13:05:19 +00:00
} else {
2019-11-21 16:05:06 +00:00
//$level--;
}
}
return $totalforeachweek ;
}
2012-02-15 22:08:20 +00:00
2009-07-28 13:37:28 +00:00
/**
* Search in task lines with a particular parent if there is a task for a particular user ( in taskrole )
2012-02-04 13:39:47 +00:00
*
2024-03-15 15:40:04 +00:00
* @ param int $inc Counter that count number of lines legitimate to show ( for return )
2012-02-04 13:39:47 +00:00
* @ param int $parent Id of parent task to start
2024-03-15 15:40:04 +00:00
* @ param Task [] $lines Array of all tasks
2025-02-10 20:20:09 +00:00
* @ param array < int , string > $taskrole Array of task filtered on a particular user
2012-02-04 13:39:47 +00:00
* @ return int 1 if there is
2009-07-28 13:37:28 +00:00
*/
2012-02-04 14:20:32 +00:00
function searchTaskInChild ( & $inc , $parent , & $lines , & $taskrole )
2009-07-28 13:37:28 +00:00
{
2013-04-12 09:09:53 +00:00
//print 'Search in line with parent id = '.$parent.'<br>';
2019-11-13 18:35:02 +00:00
$numlines = count ( $lines );
2021-02-23 21:03:23 +00:00
for ( $i = 0 ; $i < $numlines ; $i ++ ) {
2013-04-12 09:09:53 +00:00
// Process line $lines[$i]
2023-06-29 14:30:34 +00:00
if ( $lines [ $i ] -> fk_task_parent == $parent && $lines [ $i ] -> id != $lines [ $i ] -> fk_task_parent ) {
2013-04-12 09:09:53 +00:00
// If task is legitimate to show, no more need to search deeper
2021-02-23 21:03:23 +00:00
if ( isset ( $taskrole [ $lines [ $i ] -> id ])) {
2013-04-12 09:09:53 +00:00
//print 'Found a legitimate task id='.$lines[$i]->id.'<br>';
$inc ++ ;
return $inc ;
}
searchTaskInChild ( $inc , $lines [ $i ] -> id , $lines , $taskrole );
//print 'Found inc='.$inc.'<br>';
2021-02-23 21:03:23 +00:00
if ( $inc > 0 ) {
return $inc ;
}
2013-04-12 09:09:53 +00:00
}
}
return $inc ;
2009-07-28 13:37:28 +00:00
}
2010-02-20 20:24:09 +00:00
/**
* Return HTML table with list of projects and number of opened tasks
*
2024-09-22 22:37:30 +00:00
* @ param DoliDB $db Database handler
* @ param Form $form Object form
* @ param int $socid Id thirdparty
2024-09-26 00:48:16 +00:00
* @ param int | string $projectsListId Id or ids of project I have permission on ( separated with comma )
2024-09-22 22:37:30 +00:00
* @ param int < 0 , 1 > $mytasks Limited to task I am contact to
* @ param int <- 1 , 1 > $status - 1 = No filter on statut , 0 or 1 = Filter on status
* @ param array < int , string > $listofoppstatus List of opportunity status
* @ param string [] $hiddenfields List of info to not show ( 'projectlabel' , 'declaredprogress' , '...' , )
* @ param int < 0 , max > $max Max nb of record to show in HTML list
2012-02-04 13:39:47 +00:00
* @ return void
2010-02-20 20:24:09 +00:00
*/
2023-02-19 12:58:57 +00:00
function print_projecttasks_array ( $db , $form , $socid , $projectsListId , $mytasks = 0 , $status = - 1 , $listofoppstatus = array (), $hiddenfields = array (), $max = 0 )
2010-02-20 20:24:09 +00:00
{
2020-03-23 19:16:51 +00:00
global $langs , $conf , $user ;
2020-02-07 08:06:07 +00:00
global $theme_datacolor ;
2013-04-12 09:09:53 +00:00
2025-10-17 00:31:07 +00:00
$maxofloop = getDolGlobalString ( 'MAIN_MAXLIST_OVERLOAD' , 500 );
2023-02-19 12:58:57 +00:00
2013-04-12 09:09:53 +00:00
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php' ;
2020-02-07 08:06:07 +00:00
$listofstatus = array_keys ( $listofoppstatus );
2020-02-25 14:36:34 +00:00
2023-11-27 10:39:32 +00:00
if ( is_array ( $listofstatus ) && getDolGlobalString ( 'USE_COLOR_FOR_PROSPECTION_STATUS' )) {
2020-02-25 14:36:34 +00:00
// Define $themeColorId and array $statusOppList for each $listofstatus
$themeColorId = 0 ;
$statusOppList = array ();
foreach ( $listofstatus as $oppStatus ) {
$oppStatusCode = dol_getIdFromCode ( $db , $oppStatus , 'c_lead_status' , 'rowid' , 'code' );
if ( $oppStatusCode ) {
$statusOppList [ $oppStatus ][ 'code' ] = $oppStatusCode ;
$statusOppList [ $oppStatus ][ 'color' ] = isset ( $theme_datacolor [ $themeColorId ]) ? implode ( ', ' , $theme_datacolor [ $themeColorId ]) : '' ;
}
$themeColorId ++ ;
2020-02-07 08:06:07 +00:00
}
}
2019-11-13 18:35:02 +00:00
$projectstatic = new Project ( $db );
$thirdpartystatic = new Societe ( $db );
2017-06-02 10:27:46 +00:00
2019-11-13 18:35:02 +00:00
$sortfield = '' ;
$sortorder = '' ;
$project_year_filter = 0 ;
2013-04-12 09:09:53 +00:00
2019-11-13 18:35:02 +00:00
$title = $langs -> trans ( " Projects " );
2024-03-19 21:19:13 +00:00
if ( strcmp (( string ) $status , '' ) && $status >= 0 ) {
2023-11-24 09:10:24 +00:00
$title = $langs -> trans ( " Projects " ) . ' ' . $langs -> trans ( $projectstatic -> labelStatus [ $status ]);
2021-02-23 21:03:23 +00:00
}
2014-07-16 23:28:01 +00:00
2022-11-03 15:13:35 +00:00
print '<!-- print_projecttasks_array -->' ;
2017-10-19 17:53:29 +00:00
print '<div class="div-table-responsive-no-min">' ;
2019-11-05 20:24:41 +00:00
print '<table class="noborder centpercent">' ;
2013-04-12 09:09:53 +00:00
2019-11-13 18:35:02 +00:00
$sql = " FROM " . MAIN_DB_PREFIX . " projet as p " ;
2021-02-23 21:03:23 +00:00
if ( $mytasks ) {
2019-11-13 18:35:02 +00:00
$sql .= " , " . MAIN_DB_PREFIX . " projet_task as t " ;
$sql .= " , " . MAIN_DB_PREFIX . " element_contact as ec " ;
$sql .= " , " . MAIN_DB_PREFIX . " c_type_contact as ctc " ;
2020-05-21 13:05:19 +00:00
} else {
2019-11-13 18:35:02 +00:00
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " projet_task as t ON p.rowid = t.fk_projet " ;
2013-04-12 09:09:53 +00:00
}
2019-11-13 18:35:02 +00:00
$sql .= " WHERE p.entity IN ( " . getEntity ( 'project' ) . " ) " ;
2024-09-26 00:48:16 +00:00
$sql .= " AND p.rowid IN ( " . $db -> sanitize (( string ) $projectsListId ) . " ) " ;
2021-02-23 21:03:23 +00:00
if ( $socid ) {
2021-03-22 10:30:18 +00:00
$sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = " . (( int ) $socid ) . " ) " ;
2021-02-23 21:03:23 +00:00
}
if ( $mytasks ) {
2019-11-13 18:35:02 +00:00
$sql .= " AND p.rowid = t.fk_projet " ;
$sql .= " AND ec.element_id = t.rowid " ;
2021-08-23 16:56:46 +00:00
$sql .= " AND ec.fk_socpeople = " . (( int ) $user -> id );
2019-11-13 18:35:02 +00:00
$sql .= " AND ec.fk_c_type_contact = ctc.rowid " ; // Replace the 2 lines with ec.fk_c_type_contact in $arrayidtypeofcontact
$sql .= " AND ctc.element = 'project_task' " ;
2013-04-12 09:09:53 +00:00
}
2021-02-23 21:03:23 +00:00
if ( $status >= 0 ) {
2019-11-13 18:35:02 +00:00
$sql .= " AND p.fk_statut = " . ( int ) $status ;
2014-07-16 23:28:01 +00:00
}
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_LIMIT_YEAR_RANGE' )) {
2024-08-01 11:07:12 +00:00
$project_year_filter = GETPOST ( " project_year_filter " , 'alpha' ); // '*' seems allowed
2014-09-12 03:30:17 +00:00
//Check if empty or invalid year. Wildcard ignores the sql check
2021-02-23 21:03:23 +00:00
if ( $project_year_filter != " * " ) {
2024-08-01 11:07:12 +00:00
if ( empty ( $project_year_filter ) || ! is_numeric ( $project_year_filter )) {
2014-09-12 03:30:17 +00:00
$project_year_filter = date ( " Y " );
}
Qual/Sec: Use db->sanitize instead of db->escape when not quoted, fix some quoting (#39286)
* FIX phpstan: Societe::$client (int<0,3>) does not accept -1 (#39244)
Societe::$client is annotated @var int<0,3> (domain 0=no customer,
1=customer, 2=prospect, 3=both) in societe.class.php, but the create
form in societe/card.php pre-set it to -1 as a transient "nothing
pre-selected" placeholder, tripping PHPStan level 10 on develop.
The value is never persisted (save paths compute 0..3) and the only
reader, the switch() building the form, treats -1 and 0 identically via
its default case. Use 0 (the property's own default) so the assignment
matches the declared type. No behavior change.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Qual: Fix entity handling in bonprelevement.class.php
The variable name 'entities' was changed to 'entity' to better reflect the singular nature of the value being retrieved.
It was also casted to an int instead of using an unquoted db->escape.
* Qual: Improve SQL query construction in company.lib.php
By escaping the concatenated string, injection verification does not identify a false positive.
* Qual: Avoid void positive, sanitize instead of escape
* Qual: Avoid false positive, sanitize instead of escape
* Sec: Fix potential injection with cast to int (timespent_duration)
* Qual: Avoid false positive, sanitize instead of escape
* Qual: Avoid false positive, sanitize instead of escape
* fix: Replace escape() with sanitize() in SQL queries
# FIX: Replace escape() with sanitize() in SQL queries
- Replace escape() with sanitize() in SQL queries to ensure proper SQL injection protection
- Update SQL queries in multiple files to use sanitize() instead of escape()
- Ensure consistent use of sanitize() across the codebase for better security
* fix(sql): Replace escape with sanitize in SQL queries
# FIX: Replace escape with sanitize in SQL queries
- Replace `escape` with `sanitize` in SQL queries to ensure proper SQL injection prevention
* Qual: Improve field escaping/quoting
# Qual: Qual: Improve field escaping/quoting
---------
Co-authored-by: Jam Balaya <jambalaya.pyoncafe@outlook.jp>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 11:00:33 +00:00
$sql .= " AND (p.dateo IS NULL OR p.dateo <= ' " . $db -> idate ( dol_get_last_day (( int ) $project_year_filter , 12 , false )) . " ') " ;
$sql .= " AND (p.datee IS NULL OR p.datee >= ' " . $db -> idate ( dol_get_first_day (( int ) $project_year_filter , 1 , false )) . " ') " ;
2014-09-12 03:30:17 +00:00
}
}
2017-06-02 10:27:46 +00:00
2015-11-21 19:00:38 +00:00
// Get id of project we must show tasks
2019-11-13 18:35:02 +00:00
$arrayidofprojects = array ();
2024-09-22 22:37:30 +00:00
$alttext = '' ;
2015-11-21 19:00:38 +00:00
$sql1 = " SELECT p.rowid as projectid " ;
2019-11-13 18:35:02 +00:00
$sql1 .= $sql ;
2015-11-21 19:00:38 +00:00
$resql = $db -> query ( $sql1 );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2019-11-13 18:35:02 +00:00
$i = 0 ;
2015-11-21 19:00:38 +00:00
$num = $db -> num_rows ( $resql );
2021-02-23 21:03:23 +00:00
while ( $i < $num ) {
2015-11-21 19:00:38 +00:00
$objp = $db -> fetch_object ( $resql );
2019-11-13 18:35:02 +00:00
$arrayidofprojects [ $objp -> projectid ] = $objp -> projectid ;
2015-11-21 19:00:38 +00:00
$i ++ ;
}
2021-02-23 21:03:23 +00:00
} else {
dol_print_error ( $db );
}
if ( empty ( $arrayidofprojects )) {
$arrayidofprojects [ 0 ] = - 1 ;
}
2017-06-02 10:27:46 +00:00
2015-11-21 19:00:38 +00:00
// Get list of project with calculation on tasks
2020-12-08 14:03:02 +00:00
$sql2 = " SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, " ;
$sql2 .= " s.rowid as socid, s.nom as socname, s.name_alias, " ;
$sql2 .= " s.code_client, s.code_compta, s.client, " ;
$sql2 .= " s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur, " ;
$sql2 .= " s.logo, s.email, s.entity, " ;
2020-08-30 17:45:46 +00:00
$sql2 .= " p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_percent, p.opp_amount, " ;
2019-11-13 18:35:02 +00:00
$sql2 .= " p.dateo, p.datee, " ;
$sql2 .= " COUNT(t.rowid) as nb, SUM(t.planned_workload) as planned_workload, SUM(t.planned_workload * t.progress / 100) as declared_progess_workload " ;
$sql2 .= " FROM " . MAIN_DB_PREFIX . " projet as p " ;
$sql2 .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe as s ON s.rowid = p.fk_soc " ;
$sql2 .= " LEFT JOIN " . MAIN_DB_PREFIX . " projet_task as t ON p.rowid = t.fk_projet " ;
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 20:46:12 +00:00
$sql2 .= " WHERE p.rowid IN ( " . $db -> sanitize ( implode ( ',' , $arrayidofprojects )) . " ) " ;
2021-01-28 07:53:13 +00:00
$sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.rowid, s.nom, s.name_alias, s.code_client, s.code_compta, s.client, s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur, " ;
$sql2 .= " s.logo, s.email, s.entity, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_percent, p.opp_amount, p.dateo, p.datee " ;
2019-11-13 18:35:02 +00:00
$sql2 .= " ORDER BY p.title, p.ref " ;
2013-04-12 09:09:53 +00:00
2015-11-21 19:00:38 +00:00
$resql = $db -> query ( $sql2 );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2023-02-19 12:58:57 +00:00
$othernb = 0 ;
2020-10-31 13:32:18 +00:00
$total_task = 0 ;
2015-07-04 16:20:17 +00:00
$total_opp_amount = 0 ;
$ponderated_opp_amount = 0 ;
2023-02-19 12:58:57 +00:00
$total_plannedworkload = 0 ;
$total_declaredprogressworkload = 0 ;
2015-07-04 16:20:17 +00:00
2013-04-12 09:09:53 +00:00
$num = $db -> num_rows ( $resql );
2025-10-17 00:31:07 +00:00
$nbofloop = min ( $num , getDolGlobalString ( 'MAIN_MAXLIST_OVERLOAD' , 500 ));
2013-04-12 09:09:53 +00:00
$i = 0 ;
2017-10-07 11:09:31 +00:00
print '<tr class="liste_titre">' ;
2021-04-10 12:12:51 +00:00
print_liste_field_titre ( $title . '<a href="' . DOL_URL_ROOT . '/projet/list.php?search_status=' . (( int ) $status ) . '"><span class="badge marginleftonlyshort">' . $num . '</span></a>' , $_SERVER [ " PHP_SELF " ], " " , " " , " " , " " , $sortfield , $sortorder );
2019-01-27 10:55:16 +00:00
print_liste_field_titre ( " ThirdParty " , $_SERVER [ " PHP_SELF " ], " " , " " , " " , " " , $sortfield , $sortorder );
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_USE_OPPORTUNITIES' )) {
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'prospectionstatus' , $hiddenfields )) {
2021-04-15 12:20:59 +00:00
print_liste_field_titre ( " OpportunityStatus " , " " , " " , " " , " " , 'style="max-width: 100px"' , $sortfield , $sortorder , 'center ' );
2021-02-23 21:03:23 +00:00
}
2021-04-15 12:20:59 +00:00
print_liste_field_titre ( $form -> textwithpicto ( $langs -> trans ( " Amount " ), $langs -> trans ( " OpportunityAmount " ) . ' (' . $langs -> trans ( " Tooltip " ) . ' = ' . $langs -> trans ( " OpportunityWeightedAmount " ) . ')' ), " " , " " , " " , " " , 'style="max-width: 100px"' , $sortfield , $sortorder , 'right ' );
2020-06-18 01:32:13 +00:00
//print_liste_field_titre('OpportunityWeightedAmount', '', '', '', '', 'align="right"', $sortfield, $sortorder);
2017-10-07 11:09:31 +00:00
}
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_HIDE_TASKS' )) {
2019-01-27 10:55:16 +00:00
print_liste_field_titre ( " Tasks " , " " , " " , " " , " " , 'align="right"' , $sortfield , $sortorder );
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'plannedworkload' , $hiddenfields )) {
2021-02-27 11:45:07 +00:00
print_liste_field_titre ( " PlannedWorkload " , " " , " " , " " , " " , 'style="max-width: 100px"' , $sortfield , $sortorder , 'right ' );
2021-02-23 21:03:23 +00:00
}
if ( ! in_array ( 'declaredprogress' , $hiddenfields )) {
2021-02-27 11:45:07 +00:00
print_liste_field_titre ( " % " , " " , " " , " " , " " , '' , $sortfield , $sortorder , 'right ' , $langs -> trans ( " ProgressDeclared " ));
2021-02-23 21:03:23 +00:00
}
}
if ( ! in_array ( 'projectstatus' , $hiddenfields )) {
print_liste_field_titre ( " Status " , " " , " " , " " , " " , '' , $sortfield , $sortorder , 'right ' );
2017-10-07 11:09:31 +00:00
}
print " </tr> \n " ;
2017-06-02 10:27:46 +00:00
2023-02-19 12:58:57 +00:00
while ( $i < $nbofloop ) {
2013-04-12 09:09:53 +00:00
$objp = $db -> fetch_object ( $resql );
2023-02-19 12:58:57 +00:00
if ( $max && $i >= $max ) {
$othernb ++ ;
$i ++ ;
$total_task += $objp -> nb ;
$total_opp_amount += $objp -> opp_amount ;
$opp_weighted_amount = $objp -> opp_percent * $objp -> opp_amount / 100 ;
$ponderated_opp_amount += price2num ( $opp_weighted_amount );
$plannedworkload = $objp -> planned_workload ;
$total_plannedworkload += $plannedworkload ;
$declaredprogressworkload = $objp -> declared_progess_workload ;
$total_declaredprogressworkload += $declaredprogressworkload ;
continue ;
}
2013-04-12 09:09:53 +00:00
$projectstatic -> id = $objp -> projectid ;
$projectstatic -> user_author_id = $objp -> fk_user_creat ;
$projectstatic -> public = $objp -> public ;
// Check is user has read permission on project
$userAccess = $projectstatic -> restrictedProjectArea ( $user );
2021-02-23 21:03:23 +00:00
if ( $userAccess >= 0 ) {
2019-11-13 18:35:02 +00:00
$projectstatic -> ref = $objp -> ref ;
2020-02-25 12:28:11 +00:00
$projectstatic -> status = $objp -> status ;
2017-10-07 11:09:31 +00:00
$projectstatic -> title = $objp -> title ;
2022-06-22 11:50:54 +00:00
$projectstatic -> date_end = $db -> jdate ( $objp -> datee );
$projectstatic -> date_start = $db -> jdate ( $objp -> dateo );
2017-06-02 10:27:46 +00:00
2017-04-14 09:22:48 +00:00
print '<tr class="oddeven">' ;
2020-02-19 12:59:01 +00:00
2020-06-18 01:32:13 +00:00
print '<td class="tdoverflowmax150">' ;
2020-05-20 21:32:13 +00:00
print $projectstatic -> getNomUrl ( 1 , '' , 0 , '' , '-' , 0 , - 1 , 'nowraponall' );
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'projectlabel' , $hiddenfields )) {
2022-12-21 20:00:44 +00:00
print '<br><span class="opacitymedium small">' . dol_escape_htmltag ( $objp -> title ) . '</span>' ;
2021-02-23 21:03:23 +00:00
}
2015-11-21 14:31:27 +00:00
print '</td>' ;
2020-06-18 01:32:13 +00:00
2020-05-15 15:14:28 +00:00
print '<td class="nowraponall tdoverflowmax100">' ;
2021-02-23 21:03:23 +00:00
if ( $objp -> fk_soc > 0 ) {
2020-12-08 14:03:02 +00:00
$thirdpartystatic -> id = $objp -> socid ;
2019-11-13 18:35:02 +00:00
$thirdpartystatic -> name = $objp -> socname ;
2020-12-08 14:03:02 +00:00
//$thirdpartystatic->name_alias = $objp->name_alias;
//$thirdpartystatic->code_client = $objp->code_client;
$thirdpartystatic -> code_compta = $objp -> code_compta ;
2024-08-14 14:51:53 +00:00
$thirdpartystatic -> code_compta_client = $objp -> code_compta ;
2020-08-30 17:45:46 +00:00
$thirdpartystatic -> client = $objp -> client ;
2020-12-08 14:03:02 +00:00
//$thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
$thirdpartystatic -> code_compta_fournisseur = $objp -> code_compta_fournisseur ;
2020-08-30 17:45:46 +00:00
$thirdpartystatic -> fournisseur = $objp -> fournisseur ;
2020-12-08 14:03:02 +00:00
$thirdpartystatic -> logo = $objp -> logo ;
2020-08-30 17:45:46 +00:00
$thirdpartystatic -> email = $objp -> email ;
2020-12-08 14:03:02 +00:00
$thirdpartystatic -> entity = $objp -> entity ;
2017-10-07 11:09:31 +00:00
print $thirdpartystatic -> getNomUrl ( 1 );
2015-11-21 19:25:28 +00:00
}
print '</td>' ;
2020-02-19 12:59:01 +00:00
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_USE_OPPORTUNITIES' )) {
2020-02-19 12:59:01 +00:00
if ( ! in_array ( 'prospectionstatus' , $hiddenfields )) {
2020-06-18 01:32:13 +00:00
print '<td class="center tdoverflowmax75">' ;
2020-02-19 12:59:01 +00:00
// Because color of prospection status has no meaning yet, it is used if hidden constant is set
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'USE_COLOR_FOR_PROSPECTION_STATUS' )) {
2020-02-25 14:36:34 +00:00
$oppStatusCode = dol_getIdFromCode ( $db , $objp -> opp_status , 'c_lead_status' , 'rowid' , 'code' );
2020-02-21 16:53:37 +00:00
if ( $langs -> trans ( " OppStatus " . $oppStatusCode ) != " OppStatus " . $oppStatusCode ) {
print $langs -> trans ( " OppStatus " . $oppStatusCode );
2020-02-19 12:59:01 +00:00
}
} else {
if ( isset ( $statusOppList [ $objp -> opp_status ])) {
$oppStatusCode = $statusOppList [ $objp -> opp_status ][ 'code' ];
$oppStatusColor = $statusOppList [ $objp -> opp_status ][ 'color' ];
} else {
$oppStatusCode = dol_getIdFromCode ( $db , $objp -> opp_status , 'c_lead_status' , 'rowid' , 'code' );
$oppStatusColor = '' ;
}
if ( $oppStatusCode ) {
if ( ! empty ( $oppStatusColor )) {
2020-02-21 16:53:37 +00:00
print '<a href="' . dol_buildpath ( '/projet/list.php?search_opp_status=' . $objp -> opp_status , 1 ) . '" style="display: inline-block; width: 4px; border: 5px solid rgb(' . $oppStatusColor . '); border-radius: 2px;" title="' . $langs -> trans ( " OppStatus " . $oppStatusCode ) . '"></a>' ;
2020-02-19 12:59:01 +00:00
} else {
2020-02-21 16:53:37 +00:00
print '<a href="' . dol_buildpath ( '/projet/list.php?search_opp_status=' . $objp -> opp_status , 1 ) . '" title="' . $langs -> trans ( " OppStatus " . $oppStatusCode ) . '">' . $oppStatusCode . '</a>' ;
2020-02-19 12:59:01 +00:00
}
}
}
print '</td>' ;
}
2019-03-14 13:18:44 +00:00
print '<td class="right">' ;
2025-01-27 08:48:29 +00:00
$alttext = '' ;
2020-06-18 01:32:13 +00:00
if ( $objp -> opp_percent && $objp -> opp_amount ) {
$opp_weighted_amount = $objp -> opp_percent * $objp -> opp_amount / 100 ;
$alttext = $langs -> trans ( " OpportunityWeightedAmount " ) . ' ' . price ( $opp_weighted_amount , 0 , '' , 1 , - 1 , 0 , $conf -> currency );
$ponderated_opp_amount += price2num ( $opp_weighted_amount );
}
2021-02-23 21:03:23 +00:00
if ( $objp -> opp_amount ) {
2021-04-15 12:20:59 +00:00
print '<span class="amount" title="' . $alttext . '">' . $form -> textwithpicto ( price ( $objp -> opp_amount , 0 , '' , 1 , - 1 , 0 ), $alttext ) . '</span>' ;
2021-02-23 21:03:23 +00:00
}
2015-06-29 23:34:17 +00:00
print '</td>' ;
2015-07-04 16:20:17 +00:00
}
2020-02-19 12:59:01 +00:00
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_HIDE_TASKS' )) {
2019-03-14 13:18:44 +00:00
print '<td class="right">' . $objp -> nb . '</td>' ;
2017-10-07 11:09:31 +00:00
2019-11-13 18:35:02 +00:00
$plannedworkload = $objp -> planned_workload ;
$total_plannedworkload += $plannedworkload ;
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'plannedworkload' , $hiddenfields )) {
2023-12-04 11:05:28 +00:00
print '<td class="right nowraponall">' . ( $plannedworkload ? convertSecondToTime ( $plannedworkload ) : '' ) . '</td>' ;
2017-10-07 11:09:31 +00:00
}
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'declaredprogress' , $hiddenfields )) {
2019-11-13 18:35:02 +00:00
$declaredprogressworkload = $objp -> declared_progess_workload ;
$total_declaredprogressworkload += $declaredprogressworkload ;
2022-11-03 15:13:35 +00:00
print '<td class="right nowraponall">' ;
2017-10-07 11:09:31 +00:00
//print $objp->planned_workload.'-'.$objp->declared_progess_workload."<br>";
2023-12-04 11:05:28 +00:00
print ( $plannedworkload ? round ( 100 * $declaredprogressworkload / $plannedworkload , 0 ) . '%' : '' );
2017-10-07 11:09:31 +00:00
print '</td>' ;
}
2015-11-21 19:00:38 +00:00
}
2017-06-02 10:27:46 +00:00
2020-02-19 12:59:01 +00:00
if ( ! in_array ( 'projectstatus' , $hiddenfields )) {
print '<td class="right">' ;
print $projectstatic -> getLibStatut ( 3 );
print '</td>' ;
2020-02-07 08:06:07 +00:00
}
2020-02-19 12:59:01 +00:00
2013-04-12 09:09:53 +00:00
print " </tr> \n " ;
2015-07-04 16:20:17 +00:00
2023-02-19 12:58:57 +00:00
$total_task += $objp -> nb ;
$total_opp_amount += $objp -> opp_amount ;
2013-04-12 09:09:53 +00:00
}
$i ++ ;
}
2023-02-19 12:58:57 +00:00
if ( $othernb ) {
print '<tr class="oddeven">' ;
print '<td class="nowrap" colspan="5">' ;
print '<span class="opacitymedium">' . $langs -> trans ( " More " ) . '...' . ( $othernb < $maxofloop ? ' (' . $othernb . ')' : '' ) . '</span>' ;
print '</td>' ;
print " </tr> \n " ;
}
2015-11-21 14:31:27 +00:00
print '<tr class="liste_total">' ;
2020-06-18 01:32:13 +00:00
print '<td>' . $langs -> trans ( " Total " ) . " </td><td></td> " ;
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_USE_OPPORTUNITIES' )) {
2020-02-19 12:59:01 +00:00
if ( ! in_array ( 'prospectionstatus' , $hiddenfields )) {
print '<td class="liste_total"></td>' ;
}
2020-06-18 01:32:13 +00:00
print '<td class="liste_total right">' ;
//$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1);
2021-04-15 12:20:59 +00:00
print $form -> textwithpicto ( price ( $total_opp_amount , 0 , '' , 1 , - 1 , 0 ), $langs -> trans ( " OpportunityPonderatedAmountDesc " ) . ' : ' . price ( $ponderated_opp_amount , 0 , '' , 1 , - 1 , 0 , $conf -> currency ));
2020-06-18 01:32:13 +00:00
print '</td>' ;
2015-07-10 08:42:42 +00:00
}
2023-11-27 10:39:32 +00:00
if ( ! getDolGlobalString ( 'PROJECT_HIDE_TASKS' )) {
2019-03-14 13:18:44 +00:00
print '<td class="liste_total right">' . $total_task . '</td>' ;
2021-02-23 21:03:23 +00:00
if ( ! in_array ( 'plannedworkload' , $hiddenfields )) {
2023-12-04 11:05:28 +00:00
print '<td class="liste_total right">' . ( $total_plannedworkload ? convertSecondToTime ( $total_plannedworkload ) : '' ) . '</td>' ;
2021-02-23 21:03:23 +00:00
}
if ( ! in_array ( 'declaredprogress' , $hiddenfields )) {
2023-12-04 11:05:28 +00:00
print '<td class="liste_total right">' . ( $total_plannedworkload ? round ( 100 * $total_declaredprogressworkload / $total_plannedworkload , 0 ) . '%' : '' ) . '</td>' ;
2021-02-23 21:03:23 +00:00
}
2015-11-21 19:00:38 +00:00
}
2020-02-19 12:59:01 +00:00
if ( ! in_array ( 'projectstatus' , $hiddenfields )) {
print '<td class="liste_total"></td>' ;
}
2017-10-07 11:09:31 +00:00
print '</tr>' ;
2017-06-02 10:27:46 +00:00
2013-04-12 09:09:53 +00:00
$db -> free ( $resql );
2020-05-21 13:05:19 +00:00
} else {
2013-04-12 09:09:53 +00:00
dol_print_error ( $db );
}
2014-09-12 03:30:17 +00:00
2013-04-12 09:09:53 +00:00
print " </table> " ;
2017-10-19 17:53:29 +00:00
print '</div>' ;
2014-09-12 03:30:17 +00:00
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_LIMIT_YEAR_RANGE' )) {
2014-09-12 03:30:17 +00:00
//Add the year filter input
2026-05-05 09:02:35 +00:00
print '<form method="GET" action="' . dolBuildUrl ( $_SERVER [ " PHP_SELF " ]) . '">' ;
print '<table class="centpercent">' ;
2014-09-12 03:30:17 +00:00
print '<tr>' ;
print '<td>' . $langs -> trans ( " Year " ) . '</td>' ;
2023-12-30 18:50:41 +00:00
print '<td class="right"><input type="text" size="4" class="flat" name="project_year_filter" value="' . (( int ) $project_year_filter ) . '"/>' ;
2014-09-12 03:30:17 +00:00
print " </tr> \n " ;
2026-05-05 09:02:35 +00:00
print '</table>' ;
print '</form>' ;
2014-09-12 03:30:17 +00:00
}
2009-01-14 23:36:51 +00:00
}
2019-08-10 13:41:21 +00:00
/**
2019-11-26 17:59:26 +00:00
* @ param Task $task the task object
2024-01-13 18:48:20 +00:00
* @ param bool | string $label true = auto , false = don ' t display , string = replace output
* @ param bool | string $progressNumber true = auto , false = don ' t display , string = replace output
2019-11-26 17:59:26 +00:00
* @ param bool $hideOnProgressNull hide if progress is null
* @ param bool $spaced used to add space at bottom ( made by css )
2019-08-10 13:41:21 +00:00
* @ return string
2019-11-01 22:16:08 +00:00
* @ see getTaskProgressBadge ()
2019-08-10 13:41:21 +00:00
*/
2019-08-12 13:24:07 +00:00
function getTaskProgressView ( $task , $label = true , $progressNumber = true , $hideOnProgressNull = false , $spaced = false )
2019-08-10 13:41:21 +00:00
{
2020-10-31 13:32:18 +00:00
global $langs , $conf ;
$out = '' ;
$plannedworkloadoutputformat = 'allhourmin' ;
$timespentoutputformat = 'allhourmin' ;
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_PLANNED_WORKLOAD_FORMAT' )) {
2024-01-05 03:18:53 +00:00
$plannedworkloadoutputformat = getDolGlobalString ( 'PROJECT_PLANNED_WORKLOAD_FORMAT' );
2021-02-23 21:03:23 +00:00
}
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'PROJECT_TIMES_SPENT_FORMAT' )) {
2024-01-05 03:18:53 +00:00
$timespentoutputformat = getDolGlobalString ( 'PROJECT_TIME_SPENT_FORMAT' );
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
if ( empty ( $task -> progress ) && ! empty ( $hideOnProgressNull )) {
return '' ;
}
$spaced = ! empty ( $spaced ) ? 'spaced' : '' ;
$diff = '' ;
// define progress color according to time spend vs workload
$progressBarClass = 'progress-bar-info' ;
2021-06-03 06:33:44 +00:00
$progressCalculated = 0 ;
2020-10-31 13:32:18 +00:00
if ( $task -> planned_workload ) {
2023-12-27 11:12:20 +00:00
$progressCalculated = round ( 100 * ( float ) $task -> duration_effective / ( float ) $task -> planned_workload , 2 );
2020-10-31 13:32:18 +00:00
2024-01-13 18:48:20 +00:00
// this conf is actually hidden, by default we use 10% for "be careful or warning"
2023-11-27 10:39:32 +00:00
$warningRatio = getDolGlobalString ( 'PROJECT_TIME_SPEND_WARNING_PERCENT' ) ? ( 1 + $conf -> global -> PROJECT_TIME_SPEND_WARNING_PERCENT / 100 ) : 1.10 ;
2020-10-31 13:32:18 +00:00
2023-04-07 21:51:41 +00:00
$diffTitle = '<br>' . $langs -> trans ( 'ProgressDeclared' ) . ' : ' . $task -> progress . ( isset ( $task -> progress ) ? '%' : '' );
$diffTitle .= '<br>' . $langs -> trans ( 'ProgressCalculated' ) . ' : ' . $progressCalculated . ( isset ( $progressCalculated ) ? '%' : '' );
2020-10-31 13:32:18 +00:00
2021-05-20 07:22:55 +00:00
//var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.floatval($task->progress * $warningRatio));
2023-12-27 11:12:20 +00:00
if (( float ) $progressCalculated > ( float ) ( $task -> progress * $warningRatio )) {
2020-10-31 13:32:18 +00:00
$progressBarClass = 'progress-bar-danger' ;
$title = $langs -> trans ( 'TheReportedProgressIsLessThanTheCalculatedProgressionByX' , abs ( $task -> progress - $progressCalculated ) . ' ' . $langs -> trans ( " point " ));
$diff = '<span class="text-danger classfortooltip paddingrightonly" title="' . dol_htmlentities ( $title . $diffTitle ) . '" ><i class="fa fa-caret-down"></i> ' . ( $task -> progress - $progressCalculated ) . '%</span>' ;
2023-12-27 11:12:20 +00:00
} elseif (( float ) $progressCalculated > ( float ) $task -> progress ) { // warning if close at 10%
2020-10-31 13:32:18 +00:00
$progressBarClass = 'progress-bar-warning' ;
$title = $langs -> trans ( 'TheReportedProgressIsLessThanTheCalculatedProgressionByX' , abs ( $task -> progress - $progressCalculated ) . ' ' . $langs -> trans ( " point " ));
$diff = '<span class="text-warning classfortooltip paddingrightonly" title="' . dol_htmlentities ( $title . $diffTitle ) . '" ><i class="fa fa-caret-left"></i> ' . ( $task -> progress - $progressCalculated ) . '%</span>' ;
} else {
$progressBarClass = 'progress-bar-success' ;
$title = $langs -> trans ( 'TheReportedProgressIsMoreThanTheCalculatedProgressionByX' , ( $task -> progress - $progressCalculated ) . ' ' . $langs -> trans ( " point " ));
$diff = '<span class="text-success classfortooltip paddingrightonly" title="' . dol_htmlentities ( $title . $diffTitle ) . '" ><i class="fa fa-caret-up"></i> ' . ( $task -> progress - $progressCalculated ) . '%</span>' ;
}
}
$out .= '<div class="progress-group">' ;
2021-02-23 21:03:23 +00:00
if ( $label !== false ) {
2020-10-31 13:32:18 +00:00
$out .= ' <span class="progress-text">' ;
if ( $label !== true ) {
$out .= $label ; // replace label by param
} else {
$out .= $task -> getNomUrl ( 1 ) . ' ' . dol_htmlentities ( $task -> label );
}
$out .= ' </span>' ;
}
2021-02-23 21:03:23 +00:00
if ( $progressNumber !== false ) {
2020-10-31 13:32:18 +00:00
$out .= ' <span class="progress-number">' ;
if ( $progressNumber !== true ) {
$out .= $progressNumber ; // replace label by param
} else {
2021-02-23 21:03:23 +00:00
if ( $task -> hasDelay ()) {
$out .= img_warning ( $langs -> trans ( " Late " )) . ' ' ;
}
2019-08-10 13:41:21 +00:00
2019-12-01 09:08:43 +00:00
$url = DOL_URL_ROOT . '/projet/tasks/time.php?id=' . $task -> id ;
2019-08-10 13:41:21 +00:00
2020-10-31 13:32:18 +00:00
$out .= ! empty ( $diff ) ? $diff . ' ' : '' ;
2019-12-01 09:08:43 +00:00
$out .= '<a href="' . $url . '" >' ;
2020-10-31 13:32:18 +00:00
$out .= '<b title="' . $langs -> trans ( 'TimeSpent' ) . '" >' ;
2021-02-23 21:03:23 +00:00
if ( $task -> duration_effective ) {
$out .= convertSecondToTime ( $task -> duration_effective , $timespentoutputformat );
} else {
$out .= '--:--' ;
}
2020-10-31 13:32:18 +00:00
$out .= '</b>' ;
2019-12-01 09:08:43 +00:00
$out .= '</a>' ;
2019-08-10 13:41:21 +00:00
2020-10-31 13:32:18 +00:00
$out .= ' / ' ;
2019-08-10 13:41:21 +00:00
2019-12-01 09:08:43 +00:00
$out .= '<a href="' . $url . '" >' ;
2020-10-31 13:32:18 +00:00
$out .= '<span title="' . $langs -> trans ( 'PlannedWorkload' ) . '" >' ;
2021-02-23 21:03:23 +00:00
if ( $task -> planned_workload ) {
$out .= convertSecondToTime ( $task -> planned_workload , $plannedworkloadoutputformat );
} else {
$out .= '--:--' ;
}
2019-12-01 09:08:43 +00:00
$out .= '</a>' ;
2020-10-31 13:32:18 +00:00
}
$out .= ' </span>' ;
}
$out .= '</span>' ;
2024-03-28 09:55:44 +00:00
$out .= ' <div class="progress sm' . ( $spaced ? $spaced : '' ) . '">' ;
2023-12-27 11:12:20 +00:00
$diffval = ( float ) $task -> progress - ( float ) $progressCalculated ;
2020-10-31 13:32:18 +00:00
if ( $diffval >= 0 ) {
// good
2023-12-27 11:12:20 +00:00
$out .= ' <div class="progress-bar ' . $progressBarClass . '" style="width: ' . ( float ) $task -> progress . '%" title="' . ( float ) $task -> progress . '%">' ;
2020-10-31 13:32:18 +00:00
if ( ! empty ( $task -> progress )) {
2023-12-27 11:12:20 +00:00
$out .= ' <div class="progress-bar progress-bar-consumed" style="width: ' . ( float ) ( $progressCalculated / (( float ) $task -> progress == 0 ? 1 : $task -> progress ) * 100 ) . '%" title="' . ( float ) $progressCalculated . '%"></div>' ;
2019-11-30 09:08:55 +00:00
}
2020-10-31 13:32:18 +00:00
$out .= ' </div>' ;
} else {
// bad
2023-12-27 11:12:20 +00:00
$out .= ' <div class="progress-bar progress-bar-consumed-late" style="width: ' . ( float ) $progressCalculated . '%" title="' . ( float ) $progressCalculated . '%">' ;
$out .= ' <div class="progress-bar ' . $progressBarClass . '" style="width: ' . ( $task -> progress ? ( float ) ( $task -> progress / (( float ) $progressCalculated == 0 ? 1 : $progressCalculated ) * 100 ) . '%' : '1px' ) . '" title="' . ( float ) $task -> progress . '%"></div>' ;
2020-10-31 13:32:18 +00:00
$out .= ' </div>' ;
}
$out .= ' </div>' ;
$out .= '</div>' ;
2019-08-10 20:48:07 +00:00
2019-08-10 13:41:21 +00:00
2020-10-31 13:32:18 +00:00
return $out ;
2019-08-10 13:41:21 +00:00
}
/**
2019-11-26 17:59:26 +00:00
* @ param Task $task the task object
* @ param string $label empty = auto ( progress ), string = replace output
* @ param string $tooltip empty = auto , string = replace output
* @ return string
2019-11-01 22:16:08 +00:00
* @ see getTaskProgressView ()
2019-08-10 13:41:21 +00:00
*/
function getTaskProgressBadge ( $task , $label = '' , $tooltip = '' )
{
2020-10-31 13:32:18 +00:00
global $conf , $langs ;
$out = '' ;
$badgeClass = '' ;
2021-02-23 21:03:23 +00:00
if ( $task -> progress != '' ) {
2020-10-31 13:32:18 +00:00
// TODO : manage 100%
// define color according to time spend vs workload
$badgeClass = 'badge ' ;
if ( $task -> planned_workload ) {
2023-12-27 11:12:20 +00:00
$progressCalculated = round ( 100 * ( float ) $task -> duration_effective / ( float ) $task -> planned_workload , 2 );
2020-10-31 13:32:18 +00:00
2024-01-13 18:48:20 +00:00
// this conf is actually hidden, by default we use 10% for "be careful or warning"
2023-11-27 10:39:32 +00:00
$warningRatio = getDolGlobalString ( 'PROJECT_TIME_SPEND_WARNING_PERCENT' ) ? ( 1 + $conf -> global -> PROJECT_TIME_SPEND_WARNING_PERCENT / 100 ) : 1.10 ;
2020-10-31 13:32:18 +00:00
2023-12-27 11:12:20 +00:00
if (( float ) $progressCalculated > ( float ) ( $task -> progress * $warningRatio )) {
2020-10-31 13:32:18 +00:00
$badgeClass .= 'badge-danger' ;
2021-01-05 11:29:13 +00:00
if ( empty ( $tooltip )) {
$tooltip = $task -> progress . '% < ' . $langs -> trans ( " TimeConsumed " ) . ' ' . $progressCalculated . '%' ;
}
2023-12-27 11:12:20 +00:00
} elseif (( float ) $progressCalculated > ( float ) $task -> progress ) { // warning if close at 10%
2020-10-31 13:32:18 +00:00
$badgeClass .= 'badge-warning' ;
2021-02-23 21:03:23 +00:00
if ( empty ( $tooltip )) {
$tooltip = $task -> progress . '% < ' . $langs -> trans ( " TimeConsumed " ) . ' ' . $progressCalculated . '%' ;
}
2020-10-31 13:32:18 +00:00
} else {
$badgeClass .= 'badge-success' ;
2021-02-23 21:03:23 +00:00
if ( empty ( $tooltip )) {
$tooltip = $task -> progress . '% >= ' . $langs -> trans ( " TimeConsumed " ) . ' ' . $progressCalculated . '%' ;
}
2020-10-31 13:32:18 +00:00
}
}
}
$title = '' ;
if ( ! empty ( $tooltip )) {
$badgeClass .= ' classfortooltip' ;
$title = 'title="' . dol_htmlentities ( $tooltip ) . '"' ;
}
if ( empty ( $label )) {
$label = $task -> progress . ' %' ;
}
if ( ! empty ( $label )) {
$out = '<span class="' . $badgeClass . '" ' . $title . ' >' . $label . '</span>' ;
}
return $out ;
2019-08-12 21:33:00 +00:00
}