dolibarr 19.0.3
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2022 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
30require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34
35$hookmanager = new HookManager($db);
36
37// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
38$hookmanager->initHooks(array('projectsindex'));
39
40// Load translation files required by the page
41$langs->loadLangs(array('projects', 'companies'));
42
43$action = GETPOST('action', 'aZ09');
44$search_project_user = GETPOST('search_project_user', 'int');
45$mine = GETPOST('mode', 'aZ09') == 'mine' ? 1 : 0;
46if ($mine == 0 && $search_project_user === '') {
47 $search_project_user = (empty($user->conf->MAIN_SEARCH_PROJECT_USER_PROJECTSINDEX) ? '' : $user->conf->MAIN_SEARCH_PROJECT_USER_PROJECTSINDEX);
48}
49if ($search_project_user == $user->id) {
50 $mine = 1;
51}
52
53// Security check
54$socid = 0;
55//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement.
56if (!$user->hasRight('projet', 'lire')) {
58}
59
60$sortfield = GETPOST('sortfield', 'aZ09comma');
61$sortorder = GETPOST('sortorder', 'aZ09comma');
62
63$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT');
64
65
66/*
67 * Actions
68 */
69
70$parameters = array();
71$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
72if ($reshook < 0) {
73 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
74}
75if (empty($reshook)) {
76 if ($action == 'refresh_search_project_user') {
77 $search_project_user = GETPOST('search_project_user', 'int');
78 $tabparam = array("MAIN_SEARCH_PROJECT_USER_PROJECTSINDEX" => $search_project_user);
79
80 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
81 $result = dol_set_user_param($db, $conf, $user, $tabparam);
82 }
83}
84
85
86/*
87 * View
88 */
89
90$companystatic = new Societe($db);
91$projectstatic = new Project($db);
92$form = new Form($db);
93$formfile = new FormFile($db);
94
95$projectset = ($mine ? $mine : (empty($user->rights->projet->all->lire) ? 0 : 2));
96$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, $projectset, 1);
97//var_dump($projectsListId);
98
99
100$title = $langs->trans('ProjectsArea');
101
102$help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
103
104llxHeader('', $title, $help_url);
105
106
107//if ($mine) $title=$langs->trans("MyProjectsArea");
108
109
110// Title for combo list see all projects
111$titleall = $langs->trans("AllAllowedProjects");
112if ($user->hasRight('projet', 'all', 'lire') && !$socid) {
113 $titleall = $langs->trans("AllProjects");
114} else {
115 $titleall = $langs->trans("AllAllowedProjects").'<br><br>';
116}
117
118$morehtml = '';
119$morehtml .= '<form name="projectform" method="POST">';
120$morehtml .= '<input type="hidden" name="token" value="'.newToken().'">';
121$morehtml .= '<input type="hidden" name="action" value="refresh_search_project_user">';
122$morehtml .= '<SELECT name="search_project_user" id="search_project_user">';
123$morehtml .= '<option name="all" value="0"'.($mine ? '' : ' selected').'>'.$titleall.'</option>';
124$morehtml .= '<option name="mine" value="'.$user->id.'"'.(($search_project_user == $user->id) ? ' selected' : '').'>'.$langs->trans("ProjectsImContactFor").'</option>';
125$morehtml .= '</SELECT>';
126$morehtml .= ajax_combobox("search_project_user", array(), 0, 0, 'resolve', '-1', 'small');
127$morehtml .= '<input type="submit" class="button smallpaddingimp" name="refresh" value="'.$langs->trans("Refresh").'">';
128$morehtml .= '</form>';
129
130if ($mine) {
131 $tooltiphelp = $langs->trans("MyProjectsDesc");
132} else {
133 if ($user->hasRight('projet', 'all', 'lire') && !$socid) {
134 $tooltiphelp = $langs->trans("ProjectsDesc");
135 } else {
136 $tooltiphelp = $langs->trans("ProjectsPublicDesc");
137 }
138}
139
140print_barre_liste($form->textwithpicto($title, $tooltiphelp), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, -1, 'project', 0, $morehtml);
141
142
143// Get list of ponderated percent and colors for each status
144include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php';
145$listofoppstatus = array(); $listofopplabel = array(); $listofoppcode = array(); $colorseries = array();
146$sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label";
147$sql .= " FROM ".MAIN_DB_PREFIX."c_lead_status as cls";
148$sql .= " WHERE active=1";
149$resql = $db->query($sql);
150if ($resql) {
151 $num = $db->num_rows($resql);
152 $i = 0;
153
154 while ($i < $num) {
155 $objp = $db->fetch_object($resql);
156 $listofoppstatus[$objp->rowid] = $objp->percent;
157 $listofopplabel[$objp->rowid] = $objp->label; // default label if translation from "OppStatus".code not found.
158 $listofoppcode[$objp->rowid] = $objp->code;
159 switch ($objp->code) {
160 case 'PROSP':
161 $colorseries[$objp->rowid] = "-".$badgeStatus0;
162 break;
163 case 'QUAL':
164 $colorseries[$objp->rowid] = "-".$badgeStatus1;
165 break;
166 case 'PROPO':
167 $colorseries[$objp->rowid] = $badgeStatus1;
168 break;
169 case 'NEGO':
170 $colorseries[$objp->rowid] = $badgeStatus4;
171 break;
172 case 'LOST':
173 $colorseries[$objp->rowid] = $badgeStatus9;
174 break;
175 case 'WON':
176 $colorseries[$objp->rowid] = $badgeStatus6;
177 break;
178 default:
179 $colorseries[$objp->rowid] = $badgeStatus2;
180 break;
181 }
182 $i++;
183 }
184} else {
185 dol_print_error($db);
186}
187//var_dump($listofoppcode);
188
189
190print '<div class="fichecenter"><div class="fichethirdleft">';
191
192
193// Statistics
194include DOL_DOCUMENT_ROOT.'/projet/graph_opportunities.inc.php';
195
196// List of draft projects
197print_projecttasks_array($db, $form, $socid, $projectsListId, 0, 0, $listofoppstatus, array('projectlabel', 'plannedworkload', 'declaredprogress', 'prospectionstatus', 'projectstatus'), $max);
198
199
200print '</div><div class="fichetwothirdright">';
201
202// Latest modified projects
203$sql = "SELECT p.rowid, p.ref, p.title, p.dateo, p.datee, p.fk_statut as status, p.tms as datem";
204$sql .= ", s.rowid as socid, s.nom as name, s.name_alias";
205$sql .= ", s.code_client, s.code_compta, s.client";
206$sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur";
207$sql .= ", s.logo, s.email, s.entity";
208$sql .= ", s.canvas, s.status as thirdpartystatus";
209$sql .= " FROM ".MAIN_DB_PREFIX."projet as p";
210$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
211$sql .= " WHERE p.entity IN (".getEntity('project').")";
212if ($mine || !$user->hasRight('projet', 'all', 'lire')) {
213 $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; // If we have this test true, it also means projectset is not 2
214}
215if ($socid) {
216 $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).")";
217}
218$sql .= " ORDER BY p.tms DESC";
219$sql .= $db->plimit($max, 0);
220
221$resql = $db->query($sql);
222if ($resql) {
223 print '<div class="div-table-responsive-no-min">';
224 print '<table class="noborder centpercent">';
225 print '<tr class="liste_titre">';
226 print '<th colspan="5">'.$langs->trans("LatestModifiedProjects", $max).'</th>';
227 print '</tr>';
228
229 $num = $db->num_rows($resql);
230
231 if ($num) {
232 $i = 0;
233 while ($i < $num) {
234 $obj = $db->fetch_object($resql);
235
236 print '<tr class="oddeven">';
237 print '<td class="nowrap">';
238
239 $projectstatic->id = $obj->rowid;
240 $projectstatic->ref = $obj->ref;
241 $projectstatic->title = $obj->title;
242 $projectstatic->thirdparty_name = $obj->name;
243 $projectstatic->status = $obj->status;
244
245 $companystatic->id = $obj->socid;
246 $companystatic->name = $obj->name;
247 //$companystatic->name_alias = $obj->name_alias;
248 //$companystatic->code_client = $obj->code_client;
249 $companystatic->code_compta = $obj->code_compta;
250 $companystatic->client = $obj->client;
251 //$companystatic->code_fournisseur = $obj->code_fournisseur;
252 $companystatic->code_compta_fournisseur = $obj->code_compta_fournisseur;
253 $companystatic->fournisseur = $obj->fournisseur;
254 $companystatic->logo = $obj->logo;
255 $companystatic->email = $obj->email;
256 $companystatic->entity = $obj->entity;
257 $companystatic->canvas = $obj->canvas;
258 $companystatic->status = $obj->thirdpartystatus;
259
260 print '<table class="nobordernopadding"><tr class="nocellnopadd">';
261 print '<td width="96" class="nobordernopadding nowraponall">';
262 print $projectstatic->getNomUrl(1);
263 print '</td>';
264
265 print '<td width="16" class="nobordernopadding nowrap">';
266 print '&nbsp;';
267 print '</td>';
268
269 print '<td width="16" class="right nobordernopadding hideonsmartphone">';
270 $filename = dol_sanitizeFileName($obj->ref);
271 $filedir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($obj->ref);
272 $urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->rowid;
273 print $formfile->getDocumentsLink($projectstatic->element, $filename, $filedir);
274 print '</td></tr></table>';
275
276 print '</td>';
277
278 // Label
279 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->title).'">';
280 print dol_escape_htmltag($projectstatic->title);
281 print '</td>';
282
283 // Thirdparty
284 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($companystatic->name).'">';
285 if ($companystatic->id > 0) {
286 print $companystatic->getNomUrl(1, 'company', 16);
287 }
288 print '</td>';
289
290 // Date
291 $datem = $db->jdate($obj->datem);
292 print '<td class="center" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'">';
293 print dol_print_date($datem, 'day', 'tzuserrel');
294 print '</td>';
295
296 // Status
297 print '<td class="right">'.$projectstatic->LibStatut($obj->status, 3).'</td>';
298 print '</tr>';
299 $i++;
300 }
301 } else {
302 print '<tr><td colspan="4"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
303 }
304 print "</table></div>";
305} else {
306 dol_print_error($db);
307}
308
309
310$companystatic = new Societe($db); // We need a clean new object for next loop because current one has some properties set.
311
312// List of open projects per thirdparty
313$sql = "SELECT COUNT(p.rowid) as nb, SUM(p.opp_amount)";
314$sql .= ", s.rowid as socid, s.nom as name, s.name_alias";
315$sql .= ", s.code_client, s.code_compta, s.client";
316$sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur";
317$sql .= ", s.logo, s.email, s.entity";
318$sql .= ", s.canvas, s.status";
319$sql .= " FROM ".MAIN_DB_PREFIX."projet as p";
320$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
321$sql .= " WHERE p.entity IN (".getEntity('project').")";
322$sql .= " AND p.fk_statut = 1";
323if ($mine || !$user->hasRight('projet', 'all', 'lire')) {
324 $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; // If we have this test true, it also means projectset is not 2
325}
326if ($socid > 0) {
327 $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).")";
328}
329$sql .= " GROUP BY s.rowid, s.nom, s.name_alias, s.code_client, s.code_compta, s.client, s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur, s.logo, s.email, s.entity, s.canvas, s.status";
330$sql .= $db->order($sortfield, $sortorder);
331//$sql .= $db->plimit($max + 1, 0);
332
333$resql = $db->query($sql);
334if ($resql) {
335 $num = $db->num_rows($resql);
336 $i = 0;
337 $othernb = 0;
338
339 if ($num) {
340 print '<br>';
341
342 // Open project per thirdparty
343 print '<div class="div-table-responsive-no-min">';
344 print '<table class="noborder centpercent">';
345 print '<tr class="liste_titre">';
346 print_liste_field_titre("OpenedProjectsByThirdparties", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder);
347 print_liste_field_titre("Number", $_SERVER["PHP_SELF"], "nb", "", "", '', $sortfield, $sortorder, 'right ');
348 print "</tr>\n";
349 }
350
351 while ($i < $num) {
352 $obj = $db->fetch_object($resql);
353
354 if ($i >= $max) {
355 $othernb += $obj->nb;
356 $i++;
357 continue;
358 }
359
360 print '<tr class="oddeven">';
361 print '<td class="nowraponall tdoverflowmax100">';
362 if ($obj->socid > 0) {
363 $companystatic->id = $obj->socid;
364 $companystatic->name = $obj->name;
365 $companystatic->name_alias = $obj->name_alias;
366 $companystatic->code_client = $obj->code_client;
367 $companystatic->code_compta = $obj->code_compta;
368 $companystatic->client = $obj->client;
369 $companystatic->code_fournisseur = $obj->code_fournisseur;
370 $companystatic->code_compta_fournisseur = $obj->code_compta_fournisseur;
371 $companystatic->fournisseur = $obj->fournisseur;
372 $companystatic->logo = $obj->logo;
373 $companystatic->email = $obj->email;
374 $companystatic->entity = $obj->entity;
375 $companystatic->canvas = $obj->canvas;
376 $companystatic->status = $obj->status;
377
378 print $companystatic->getNomUrl(1);
379 } else {
380 print $langs->trans("OthersNotLinkedToThirdParty");
381 }
382 print '</td>';
383 print '<td class="right">';
384 if ($obj->socid) {
385 print '<a href="'.DOL_URL_ROOT.'/projet/list.php?socid='.$obj->socid.'&search_status=1">'.$obj->nb.'</a>';
386 } else {
387 print '<a href="'.DOL_URL_ROOT.'/projet/list.php?search_societe='.urlencode('^$').'&search_status=1">'.$obj->nb.'</a>';
388 }
389 print '</td>';
390 print "</tr>\n";
391
392 $i++;
393 }
394 if ($othernb) {
395 print '<tr class="oddeven">';
396 print '<td class="nowrap">';
397 print '<span class="opacitymedium">'.$langs->trans("More").'...</span>';
398 print '</td>';
399 print '<td class="nowrap right">';
400 print $othernb;
401 print '</td>';
402 print "</tr>\n";
403 }
404
405 if ($num) {
406 print "</table>";
407 print '</div>';
408 }
409
410 $db->free($resql);
411} else {
412 dol_print_error($db);
413}
414
415if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') || getDolGlobalInt('PROJECT_SHOW_OPEN_PROJECTS_LIST_ON_PROJECT_AREA')) {
416 // This list is surely very long and useless when we are using opportunities, so we hide it for this use case, but we allow to show it if
417 // we really want it and to allow interface backward compatibility.
418 print '<br>';
419
420 print_projecttasks_array($db, $form, $socid, $projectsListId, 0, 1, $listofoppstatus, array());
421}
422
423print '</div></div>';
424
425$parameters = array('user' => $user);
426$reshook = $hookmanager->executeHooks('dashboardProjects', $parameters, $projectstatic); // Note that $action and $object may have been modified by hook
427
428// End of page
429llxFooter();
430$db->close();
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:455
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage hooks.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
dol_set_user_param($db, $conf, &$user, $tab)
Save personnal parameter.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks=0, $status=-1, $listofoppstatus=array(), $hiddenfields=array(), $max=0)
Return HTML table with list of projects and number of opened tasks.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.