dolibarr 21.0.3
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Marc Bariley / Ocebo <marc@ocebo.com>
5 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
7 * Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
8 * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
9 * Copyright (C) 2019 Juanjo Menent <jmenent@2byte.es>
10 * Copyright (C) 2020 Tobias Sean <tobias.sekan@startmail.com>
11 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
12 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
14 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
36// Load Dolibarr environment
37require '../main.inc.php';
38require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
41require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
42require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
43require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
44if (isModEnabled('category')) {
45 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
47}
48
57// Load translation files required by the page
58$langs->loadLangs(array('projects', 'companies', 'commercial'));
59if (isModEnabled('eventorganization') && $conf->eventorganization->enabled) {
60 $langs->loadLangs(array('eventorganization'));
61}
62
63$action = GETPOST('action', 'aZ09');
64$massaction = GETPOST('massaction', 'alpha');
65$show_files = GETPOSTINT('show_files');
66$confirm = GETPOST('confirm', 'alpha');
67$toselect = GETPOST('toselect', 'array');
68$optioncss = GETPOST('optioncss', 'alpha');
69$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'projectlist';
70$mode = GETPOST('mode', 'alpha');
71$groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut'
72
73$title = $langs->trans("Projects");
74
75// Security check
76$socid = GETPOSTINT('socid');
77//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 assignment.
78if ($socid > 0) {
79 $soc = new Societe($db);
80 $soc->fetch($socid);
81 $title .= ' (<a href="list.php">'.$soc->name.'</a>)';
82}
83if (!$user->hasRight('projet', 'lire')) {
85}
86
87$diroutputmassaction = $conf->project->dir_output.'/temp/massgeneration/'.$user->id;
88
89$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
90$sortfield = GETPOST('sortfield', 'aZ09comma');
91$sortorder = GETPOST('sortorder', 'aZ09comma');
92$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
93if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
94 // If $page is not defined, or '' or -1 or if we click on clear filters
95 $page = 0;
96}
97if (!$sortfield) {
98 $sortfield = "p.ref";
99}
100if (!$sortorder) {
101 $sortorder = "ASC";
102}
103$offset = $limit * $page;
104$pageprev = $page - 1;
105$pagenext = $page + 1;
106
107$search_all = GETPOST('search_all', 'alphanohtml');
108$search_entity = GETPOSTINT('search_entity');
109$search_ref = GETPOST("search_ref", 'alpha');
110$search_label = GETPOST("search_label", 'alpha');
111$search_societe = GETPOST("search_societe", 'alpha');
112$search_societe_alias = GETPOST("search_societe_alias", 'alpha');
113$search_societe_country = GETPOST("search_societe_country", 'alpha');
114$search_opp_status = GETPOST("search_opp_status", 'alpha');
115$search_opp_percent = GETPOST("search_opp_percent", 'alpha');
116$search_opp_amount = GETPOST("search_opp_amount", 'alpha');
117$search_budget_amount = GETPOST("search_budget_amount", 'alpha');
118$search_public = GETPOST("search_public", 'intcomma');
119$search_project_user = GETPOSTINT('search_project_user');
120$search_project_contact = GETPOSTINT('search_project_contact');
121$search_sale = GETPOSTINT('search_sale');
122$search_usage_opportunity = GETPOST('search_usage_opportunity', 'intcomma');
123$search_usage_task = GETPOST('search_usage_task', 'intcomma');
124$search_usage_bill_time = GETPOST('search_usage_bill_time', 'intcomma');
125$search_usage_event_organization = GETPOST('search_usage_event_organization', 'intcomma');
126$search_accept_conference_suggestions = GETPOST('search_accept_conference_suggestions', 'intcomma');
127$search_accept_booth_suggestions = GETPOST('search_accept_booth_suggestions', 'intcomma');
128$search_price_registration = GETPOST("search_price_registration", 'alpha');
129$search_price_booth = GETPOST("search_price_booth", 'alpha');
130$search_login = GETPOST('search_login', 'alpha');
131$search_import_key = GETPOST('search_import_key', 'alpha');
132$searchCategoryCustomerOperator = 0;
133if (GETPOSTISSET('formfilteraction')) {
134 $searchCategoryCustomerOperator = GETPOSTINT('search_category_customer_operator');
135} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
136 $searchCategoryCustomerOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
137}
138$searchCategoryCustomerList = GETPOST('search_category_customer_list', 'array');
139$search_omitChildren = 0;
140if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
141 $search_omitChildren = GETPOST('search_omitChildren', 'alpha') == 'on' ? 1 : 0;
142}
143
144
145$mine = ((GETPOST('mode') == 'mine') ? 1 : 0);
146if ($mine) {
147 $search_project_user = $user->id;
148 $mine = 0;
149}
150
151$search_sday = GETPOSTINT('search_sday');
152$search_smonth = GETPOSTINT('search_smonth');
153$search_syear = GETPOSTINT('search_syear');
154$search_eday = GETPOSTINT('search_eday');
155$search_emonth = GETPOSTINT('search_emonth');
156$search_eyear = GETPOSTINT('search_eyear');
157
158$search_date_start_startmonth = GETPOSTINT('search_date_start_startmonth');
159$search_date_start_startyear = GETPOSTINT('search_date_start_startyear');
160$search_date_start_startday = GETPOSTINT('search_date_start_startday');
161$search_date_start_start = dol_mktime(0, 0, 0, $search_date_start_startmonth, $search_date_start_startday, $search_date_start_startyear); // Use tzserver
162$search_date_start_endmonth = GETPOSTINT('search_date_start_endmonth');
163$search_date_start_endyear = GETPOSTINT('search_date_start_endyear');
164$search_date_start_endday = GETPOSTINT('search_date_start_endday');
165$search_date_start_end = dol_mktime(23, 59, 59, $search_date_start_endmonth, $search_date_start_endday, $search_date_start_endyear); // Use tzserver
166
167$search_date_end_startmonth = GETPOSTINT('search_date_end_startmonth');
168$search_date_end_startyear = GETPOSTINT('search_date_end_startyear');
169$search_date_end_startday = GETPOSTINT('search_date_end_startday');
170$search_date_end_start = dol_mktime(0, 0, 0, $search_date_end_startmonth, $search_date_end_startday, $search_date_end_startyear); // Use tzserver
171$search_date_end_endmonth = GETPOSTINT('search_date_end_endmonth');
172$search_date_end_endyear = GETPOSTINT('search_date_end_endyear');
173$search_date_end_endday = GETPOSTINT('search_date_end_endday');
174$search_date_end_end = dol_mktime(23, 59, 59, $search_date_end_endmonth, $search_date_end_endday, $search_date_end_endyear); // Use tzserver
175
176$search_date_creation_startmonth = GETPOSTINT('search_date_creation_startmonth');
177$search_date_creation_startyear = GETPOSTINT('search_date_creation_startyear');
178$search_date_creation_startday = GETPOSTINT('search_date_creation_startday');
179$search_date_creation_start = dol_mktime(0, 0, 0, $search_date_creation_startmonth, $search_date_creation_startday, $search_date_creation_startyear); // Use tzserver
180$search_date_creation_endmonth = GETPOSTINT('search_date_creation_endmonth');
181$search_date_creation_endyear = GETPOSTINT('search_date_creation_endyear');
182$search_date_creation_endday = GETPOSTINT('search_date_creation_endday');
183$search_date_creation_end = dol_mktime(23, 59, 59, $search_date_creation_endmonth, $search_date_creation_endday, $search_date_creation_endyear); // Use tzserver
184
185$search_date_modif_startmonth = GETPOSTINT('search_date_modif_startmonth');
186$search_date_modif_startyear = GETPOSTINT('search_date_modif_startyear');
187$search_date_modif_startday = GETPOSTINT('search_date_modif_startday');
188$search_date_modif_start = dol_mktime(0, 0, 0, $search_date_modif_startmonth, $search_date_modif_startday, $search_date_modif_startyear); // Use tzserver
189$search_date_modif_endmonth = GETPOSTINT('search_date_modif_endmonth');
190$search_date_modif_endyear = GETPOSTINT('search_date_modif_endyear');
191$search_date_modif_endday = GETPOSTINT('search_date_modif_endday');
192$search_date_modif_end = dol_mktime(23, 59, 59, $search_date_modif_endmonth, $search_date_modif_endday, $search_date_modif_endyear); // Use tzserver
193
194$search_category_array = array();
195
196if (isModEnabled('category')) {
197 $search_category_array = GETPOST("search_category_".Categorie::TYPE_PROJECT."_list", "array");
198}
199
200if (GETPOSTISARRAY('search_status') || GETPOST('search_status_multiselect')) {
201 $search_status = implode(',', GETPOST('search_status', 'array:intcomma'));
202} else {
203 $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : (GETPOSTISSET('search_all') ? '' : '0,1'));
204}
205
206$search_option = GETPOST('search_option', 'alpha');
207if ($search_option == 'late') {
208 $search_status = '1';
209}
210// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
211$object = new Project($db);
212$hookmanager->initHooks(array('projectlist'));
213$extrafields = new ExtraFields($db);
214
215// fetch optionals attributes and labels
216$extrafields->fetch_name_optionals_label($object->table_element);
217
218$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
219
220// List of fields to search into when doing a "search in all"
221$fieldstosearchall = array();
222foreach ($object->fields as $key => $val) {
223 if (empty($val['searchall'])) {
224 continue;
225 }
226
227 // Don't allow search in private notes for external users when doing "search in all"
228 if (!empty($user->socid) && $key == "note_private") {
229 continue;
230 }
231
232 $fieldstosearchall['p.'.$key] = $val['label'];
233}
234
235// Add name object fields to "search in all"
236$fieldstosearchall['s.nom'] = "ThirdPartyName";
237$fieldstosearchall['s.name_alias'] = "AliasNameShort";
238$fieldstosearchall['s.code_client'] = "CustomerCode";
239
240// Definition of array of fields for columns
241$arrayfields = array();
242foreach ($object->fields as $key => $val) {
243 // If $val['visible']==0, then we never show the field
244 if (!empty($val['visible'])) {
245 $visible = (int) dol_eval((string) $val['visible'], 1, 1, '1');
246 $arrayfields['p.'.$key] = array(
247 'label' => $val['label'],
248 'checked' => (($visible < 0) ? 0 : 1),
249 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
250 'position' => $val['position'],
251 'help' => isset($val['help']) ? $val['help'] : ''
252 );
253 }
254}
255// Extra fields
256include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
257
258// Add non object fields to fields for list
259$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1));
260$arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => 0, 'position' => 22);
261$arrayfields['co.country_code'] = array('label' => "Country", 'checked' => -1, 'position' => 23);
262$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => 0, 'position' => 25);
263$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => 1, 'position' => 120);
264$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106);
265$arrayfields['u.login'] = array('label' => "Author", 'checked' => -1, 'position' => 165);
266// Force some fields according to search_usage filter...
267//if (GETPOST('search_usage_opportunity')) {
268//$arrayfields['p.usage_opportunity']['visible'] = 1; // Not required, filter on search_opp_status is enough
269//$arrayfields['p.usage_opportunity']['checked'] = 1; // Not required, filter on search_opp_status is enough
270//}
271if (GETPOST('search_usage_event_organization')) {
272 $arrayfields['p.fk_opp_status']['enabled'] = 0;
273 $arrayfields['p.opp_amount']['enabled'] = 0;
274 $arrayfields['p.opp_percent']['enabled'] = 0;
275 $arrayfields['opp_weighted_amount']['enabled'] = 0;
276 $arrayfields['p.usage_organize_event']['visible'] = 1;
277 $arrayfields['p.usage_organize_event']['checked'] = 1;
278}
279$arrayfields['p.fk_project']['enabled'] = 0;
280
281// Force this field to be visible
282if ($contextpage == 'lead') {
283 $arrayfields['p.fk_opp_status']['enabled'] = 1;
284 $arrayfields['p.fk_opp_status']['visible'] = 1;
285}
286
287
288$object->fields = dol_sort_array($object->fields, 'position');
289$arrayfields = dol_sort_array($arrayfields, 'position');
290'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
291
292// Add a groupby field. Set $groupby and $groupbyvalues.
293// TODO Move this into a inc file
294$groupbyvalues = array();
295$groupofcollpasedvalues = array();
296$groupbyold = null;
297if ($mode == 'kanban' && $groupby) {
298 $groupbyfield = preg_replace('/[a-z]\./', '', $groupby);
299 if (!empty($object->fields[$groupbyfield]['alias'])) {
300 $groupbyfield = $object->fields[$groupbyfield]['alias'];
301 }
302 if (!in_array(preg_replace('/[a-z]\./', '', $groupby), array_keys($object->fields))) {
303 $groupby = '';
304 } else {
305 if (!empty($object->fields[$groupby]['arrayofkeyval'])) {
306 $groupbyvalues = $object->fields[$groupby]['arrayofkeyval'];
307 } elseif (!empty($object->fields[preg_replace('/[a-z]\./', '', $groupby)]['arrayofkeyval'])) {
308 $groupbyvalues = $object->fields[preg_replace('/[a-z]\./', '', $groupby)]['arrayofkeyval'];
309 } else {
310 // var_dump($object->fields[$groupby]['type']);
311 // If type is 'integer:Object:classpath', for example "integer:CLeadStatus:core/class/cleadstatus.class.php"
312 // TODO
313 // $groupbyvalues = ...
314
315 $sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label";
316 $sql .= " FROM ".MAIN_DB_PREFIX."c_lead_status as cls";
317 $sql .= " WHERE active = 1";
318 //$sql .= " AND cls.code <> 'LOST'";
319 //$sql .= " AND cls.code <> 'WON'";
320 $sql .= $db->order('cls.rowid', 'ASC'); // Must use the same order key than the key in $groupby
321 $resql = $db->query($sql);
322 if ($resql) {
323 $num = $db->num_rows($resql);
324 $i = 0;
325
326 while ($i < $num) {
327 $objp = $db->fetch_object($resql);
328 $groupbyvalues[$objp->rowid] = $objp->label;
329 $i++;
330 }
331 }
332
333 $groupofcollpasedvalues = array(6,7); // LOST and WON
334 }
335 //var_dump($groupbyvalues);
336 }
337 // Add a filter on the group by if not yet included first
338 if ($groupby && !preg_match('/^'.preg_quote($db->sanitize($groupby), '/').'/', $sortfield)) {
339 //var_dump($arrayfields);
340 $sortfield = $db->sanitize($groupby).($sortfield ? ",".$sortfield : "");
341 $sortorder = "ASC".($sortfield ? ",".$sortorder : "");
342 }
343}
344
345
346/*
347 * Actions
348 */
349$error = 0;
350if (GETPOST('cancel', 'alpha')) {
351 $action = 'list';
352 $massaction = '';
353}
354if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
355 $massaction = '';
356}
357
358$parameters = array('socid' => $socid, 'arrayfields' => &$arrayfields);
359$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
360if ($reshook < 0) {
361 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
362}
363
364if (empty($reshook)) {
365 // Selection of new fields
366 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
367
368 // Purge search criteria
369 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
370 $search_all = '';
371 $search_ref = "";
372 $search_label = "";
373 $search_societe = "";
374 $search_societe_alias = '';
375 $search_societe_country = '';
376 $search_status = -1;
377 $search_option = '';
378 $search_opp_status = -1;
379 $search_opp_amount = '';
380 $search_opp_percent = '';
381 $search_budget_amount = '';
382 $search_public = "";
383 $search_sale = "";
384 $search_project_user = '';
385 $search_project_contact = '';
386 $search_sday = "";
387 $search_smonth = "";
388 $search_syear = "";
389 $search_eday = "";
390 $search_emonth = "";
391 $search_eyear = "";
392 $search_date_start_startmonth = "";
393 $search_date_start_startyear = "";
394 $search_date_start_startday = "";
395 $search_date_start_start = "";
396 $search_date_start_endmonth = "";
397 $search_date_start_endyear = "";
398 $search_date_start_endday = "";
399 $search_date_start_end = "";
400 $search_date_end_startmonth = "";
401 $search_date_end_startyear = "";
402 $search_date_end_startday = "";
403 $search_date_end_start = "";
404 $search_date_end_endmonth = "";
405 $search_date_end_endyear = "";
406 $search_date_end_endday = "";
407 $search_date_end_end = "";
408 $search_date_creation_startmonth = "";
409 $search_date_creation_startyear = "";
410 $search_date_creation_startday = "";
411 $search_date_creation_start = "";
412 $search_date_creation_endmonth = "";
413 $search_date_creation_endyear = "";
414 $search_date_creation_endday = "";
415 $search_date_creation_end = "";
416 $search_date_modif_startmonth = "";
417 $search_date_modif_startyear = "";
418 $search_date_modif_startday = "";
419 $search_date_modif_start = "";
420 $search_date_modif_endmonth = "";
421 $search_date_modif_endyear = "";
422 $search_date_modif_endday = "";
423 $search_date_modif_end = "";
424 $search_usage_opportunity = '';
425 $search_usage_task = '';
426 $search_usage_bill_time = '';
427 $search_usage_event_organization = '';
428 $search_accept_conference_suggestions = '';
429 $search_accept_booth_suggestions = '';
430 $search_price_registration = '';
431 $search_price_booth = '';
432 $search_login = '';
433 $search_import_key = '';
434 $search_entity = '';
435 $toselect = array();
436 $search_array_options = array();
437 $search_category_array = array();
438 }
439
440
441 // Mass actions
442 $objectclass = 'Project';
443 $objectlabel = 'Project';
444 $permissiontoread = $user->hasRight('projet', 'lire');
445 $permissiontodelete = $user->hasRight('projet', 'supprimer');
446 $permissiontoadd = $user->hasRight('projet', 'creer');
447 $uploaddir = $conf->project->dir_output;
448
449 global $error;
450 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
451
452 // Close records
453 if (!$error && $massaction == 'close' && $user->hasRight('projet', 'creer')) {
454 $db->begin();
455
456 $objecttmp = new $objectclass($db);
457 $nbok = 0;
458 foreach ($toselect as $toselectid) {
459 $result = $objecttmp->fetch($toselectid);
460 if ($result > 0) {
461 $userWrite = $object->restrictedProjectArea($user, 'write');
462 if ($userWrite > 0 && $objecttmp->statut == 1) {
463 $result = $objecttmp->setClose($user);
464 if ($result <= 0) {
465 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
466 $error++;
467 break;
468 } else {
469 $nbok++;
470 }
471 } elseif ($userWrite <= 0) {
472 setEventMessages($langs->trans("DontHavePermissionForCloseProject", $objecttmp->ref), null, 'warnings');
473 } else {
474 setEventMessages($langs->trans("DontHaveTheValidateStatus", $objecttmp->ref), null, 'warnings');
475 }
476 } else {
477 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
478 $error++;
479 break;
480 }
481 }
482
483 if (!$error) {
484 setEventMessages($langs->trans("RecordsClosed", $nbok), null, 'mesgs');
485 $db->commit();
486 } else {
487 $db->rollback();
488 }
489 }
490}
491
492
493/*
494 * View
495 */
496
497unset($_SESSION['pageforbacktolist']['project']);
498
499$form = new Form($db);
500$formcompany = new FormCompany($db);
501
502$now = dol_now();
503
504$companystatic = new Societe($db);
505$taskstatic = new Task($db);
506$formother = new FormOther($db);
507$formproject = new FormProjets($db);
508$userstatic = new User($db);
509
510$help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
511$title = $langs->trans("LeadsOrProjects");
512if (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
513 $title = $langs->trans("Projects");
514}
515if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
516 $title = $langs->trans("Leads");
517}
518$morejs = array();
519$morecss = array();
520
521
522// Get list of project id allowed to user (in a string list separated by comma)
523$projectsListId = '';
524if (!$user->hasRight('projet', 'all', 'lire')) {
525 $projectsListId = $object->getProjectsAuthorizedForUser($user, 0, 1, $socid);
526}
527
528// Get id of types of contacts for projects (This list never contains a lot of elements)
529$listofprojectcontacttype = array();
530$listofprojectcontacttypeexternal = array();
531$sql = "SELECT ctc.rowid, ctc.code, ctc.source FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
532$sql .= " WHERE ctc.element = '".$db->escape($object->element)."'";
533$resql = $db->query($sql);
534if ($resql) {
535 while ($obj = $db->fetch_object($resql)) {
536 if ($obj->source == 'internal') {
537 $listofprojectcontacttype[$obj->rowid] = $obj->code;
538 } else {
539 $listofprojectcontacttypeexternal[$obj->rowid] = $obj->code;
540 }
541 }
542} else {
543 dol_print_error($db);
544}
545if (count($listofprojectcontacttype) == 0) {
546 $listofprojectcontacttype[0] = '0'; // To avoid sql syntax error if not found
547}
548if (count($listofprojectcontacttypeexternal) == 0) {
549 $listofprojectcontacttypeexternal[0] = '0'; // To avoid sql syntax error if not found
550}
551
552$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
553$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
554
555$sql = "SELECT p.rowid as id, p.ref, p.title, p.fk_statut as status, p.fk_opp_status, p.public, p.fk_user_creat,";
556$sql .= " p.datec as date_creation, p.dateo as date_start, p.datee as date_end, p.opp_amount, p.opp_percent, (p.opp_amount * p.opp_percent / 100) as opp_weighted_amount, p.tms as date_modification, p.budget_amount,";
557$sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,";
558$sql .= " p.email_msgid, p.import_key,";
559$sql .= " p.accept_conference_suggestions, p.accept_booth_suggestions, p.price_registration, p.price_booth,";
560$sql .= " s.rowid as socid, s.nom as name, s.name_alias as alias, s.email, s.email, s.phone, s.fax, s.address, s.town, s.zip, s.fk_pays, s.client, s.code_client,";
561$sql .= " country.code as country_code,";
562$sql .= " cls.code as opp_status_code,";
563$sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender';
564// Add fields from extrafields
565if (!empty($extrafields->attributes[$object->table_element]['label'])) {
566 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
567 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
568 }
569}
570// Add fields from hooks
571$parameters = array();
572$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
573$sql .= $hookmanager->resPrint;
574$sql = preg_replace('/,\s*$/', '', $sql);
575
576$sqlfields = $sql; // $sql fields to remove for count total
577
578$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as p";
579if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
580 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (p.rowid = ef.fk_object)";
581}
582$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
583$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on country.rowid = s.fk_pays";
584$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls on p.fk_opp_status = cls.rowid";
585$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user AS u ON p.fk_user_creat = u.rowid';
586// We'll need this table joined to the select in order to filter by sale
587// No check is done on company permission because readability is managed by public status of project and assignment.
588//if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid";
589
590$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
591$sql .= $hookmanager->resPrint;
592if ($search_entity > 0) {
593 $sql .= " WHERE p.entity = ".((int) $search_entity);
594} else {
595 $sql .= " WHERE p.entity IN (".getEntity('project').')';
596}
597if (!$user->hasRight('projet', 'all', 'lire')) {
598 $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; // public and assigned to, or restricted to company for external users
599}
600// No need to check if company is external user, as filtering of projects must be done by getProjectsAuthorizedForUser
601if ($socid > 0) {
602 $sql .= " AND (p.fk_soc = ".((int) $socid).")"; // This filter if when we use a hard coded filter on company on url (not related to filter for external users)
603}
604if ($search_ref) {
605 $sql .= natural_search('p.ref', $search_ref);
606}
607if ($search_label) {
608 $sql .= natural_search('p.title', $search_label);
609}
610if (empty($arrayfields['s.name_alias']['checked']) && $search_societe) {
611 $sql .= natural_search(array("s.nom", "s.name_alias"), $search_societe);
612} else {
613 if ($search_societe) {
614 $sql .= natural_search('s.nom', $search_societe);
615 }
616 if ($search_societe_alias) {
617 $sql .= natural_search('s.name_alias', $search_societe_alias);
618 }
619}
620if ($search_societe_country) {
621 $sql .= natural_search('country.code', $search_societe_country);
622}
623if ($search_opp_amount) {
624 $sql .= natural_search('p.opp_amount', $search_opp_amount, 1);
625}
626if ($search_opp_percent) {
627 $sql .= natural_search('p.opp_percent', $search_opp_percent, 1);
628}
629$sql .= dolSqlDateFilter('p.dateo', $search_sday, $search_smonth, $search_syear);
630$sql .= dolSqlDateFilter('p.datee', $search_eday, $search_emonth, $search_eyear);
631
632if ($search_date_start_start) {
633 $sql .= " AND p.dateo >= '".$db->idate($search_date_start_start)."'";
634}
635if ($search_date_start_end) {
636 $sql .= " AND p.dateo <= '".$db->idate($search_date_start_end)."'";
637}
638
639if ($search_date_end_start) {
640 $sql .= " AND p.datee >= '".$db->idate($search_date_end_start)."'";
641}
642if ($search_date_end_end) {
643 $sql .= " AND p.datee <= '".$db->idate($search_date_end_end)."'";
644}
645
646if ($search_date_creation_start) {
647 $sql .= " AND p.datec >= '".$db->idate($search_date_creation_start)."'";
648}
649if ($search_date_creation_end) {
650 $sql .= " AND p.datec <= '".$db->idate($search_date_creation_end)."'";
651}
652
653if ($search_date_modif_start) {
654 $sql .= " AND p.tms >= '".$db->idate($search_date_modif_start)."'";
655}
656if ($search_date_modif_end) {
657 $sql .= " AND p.tms <= '".$db->idate($search_date_modif_end)."'";
658}
659
660if ($search_all) {
661 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
662}
663if ($search_status != '' && $search_status != '-1') {
664 if ($search_status == 99) {
665 $sql .= " AND p.fk_statut IN (0,1)";
666 } else {
667 $sql .= " AND p.fk_statut IN (".$db->sanitize($db->escape($search_status)).")";
668 }
669}
670if ($search_option == 'late') {
671 $sql .= " AND p.datee < '".$db->idate(dol_now() - $conf->project->warning_delay)."'";
672}
673if ($search_opp_status) {
674 if (is_numeric($search_opp_status) && $search_opp_status > 0) {
675 $sql .= " AND p.fk_opp_status = ".((int) $search_opp_status);
676 }
677 if ($search_opp_status == 'all') {
678 $sql .= " AND (p.fk_opp_status IS NOT NULL AND p.fk_opp_status <> -1)";
679 }
680 if ($search_opp_status == 'openedopp') {
681 $sql .= " AND p.fk_opp_status IS NOT NULL AND p.fk_opp_status <> -1 AND p.fk_opp_status NOT IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code IN ('WON','LOST'))";
682 }
683 if ($search_opp_status == 'notopenedopp') {
684 $sql .= " AND (p.fk_opp_status IS NULL OR p.fk_opp_status = -1 OR p.fk_opp_status IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code = 'WON'))";
685 }
686 if ($search_opp_status == 'none') {
687 $sql .= " AND (p.fk_opp_status IS NULL OR p.fk_opp_status = -1)";
688 }
689}
690if ($search_public != '') {
691 $sql .= " AND p.public = ".((int) $search_public);
692}
693// No check is done on company permission because readability is managed by public status of project and assignment.
694//if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id).") OR (s.rowid IS NULL))";
695// Search on sale representative
696if ($search_sale && $search_sale != '-1') {
697 if ($search_sale == -2) {
698 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
699 } elseif ($search_sale > 0) {
700 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
701 }
702}
703if ($search_project_user > 0) {
704 $sql .= " AND EXISTS (SELECT ecp.rowid FROM ".MAIN_DB_PREFIX."element_contact as ecp WHERE ecp.fk_c_type_contact IN (".$db->sanitize(implode(',', array_keys($listofprojectcontacttype))).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".((int) $search_project_user).")";
705}
706if ($search_project_contact > 0) {
707 $sql .= " AND EXISTS (SELECT ecp_contact.rowid FROM ".MAIN_DB_PREFIX."element_contact as ecp_contact WHERE ecp_contact.fk_c_type_contact IN (".$db->sanitize(implode(',', array_keys($listofprojectcontacttypeexternal))).") AND ecp_contact.element_id = p.rowid AND ecp_contact.fk_socpeople = ".((int) $search_project_contact).")";
708}
709if ($search_opp_amount != '') {
710 $sql .= natural_search('p.opp_amount', $search_opp_amount, 1);
711}
712if ($search_budget_amount != '') {
713 $sql .= natural_search('p.budget_amount', $search_budget_amount, 1);
714}
715if ($search_usage_opportunity != '' && $search_usage_opportunity >= 0) {
716 $sql .= natural_search('p.usage_opportunity', $search_usage_opportunity, 2);
717}
718if ($search_usage_task != '' && $search_usage_task >= 0) {
719 $sql .= natural_search('p.usage_task', $search_usage_task, 2);
720}
721if ($search_usage_bill_time != '' && $search_usage_bill_time >= 0) {
722 $sql .= natural_search('p.usage_bill_time', $search_usage_bill_time, 2);
723}
724if ($search_usage_event_organization != '' && $search_usage_event_organization >= 0) {
725 $sql .= natural_search('p.usage_organize_event', $search_usage_event_organization, 2);
726}
727if ($search_accept_conference_suggestions != '' && $search_accept_conference_suggestions >= 0) {
728 $sql .= natural_search('p.accept_conference_suggestions', $search_accept_conference_suggestions, 2);
729}
730if ($search_accept_booth_suggestions != '' && $search_accept_booth_suggestions >= 0) {
731 $sql .= natural_search('p.accept_booth_suggestions', $search_accept_booth_suggestions, 2);
732}
733if ($search_price_registration != '') {
734 $sql .= natural_search('p.price_registration', $search_price_registration, 1);
735}
736if ($search_price_booth != '') {
737 $sql .= natural_search('p.price_booth', $search_price_booth, 1);
738}
739if ($search_login) {
740 $sql .= natural_search(array('u.login', 'u.firstname', 'u.lastname'), $search_login);
741}
742if ($search_import_key) {
743 $sql .= natural_search(array('p.import_key'), $search_import_key);
744}
745if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
746 if ($search_omitChildren == 1) {
747 $sql .= " AND p.fk_project IS NULL";
748 }
749}
750
751// Search for tag/category ($searchCategoryProjectList is an array of ID)
752$searchCategoryProjectList = $search_category_array;
753$searchCategoryProjectOperator = 0;
754if (!empty($searchCategoryProjectList)) {
755 $searchCategoryProjectSqlList = array();
756 $listofcategoryid = '';
757 foreach ($searchCategoryProjectList as $searchCategoryProject) {
758 if (intval($searchCategoryProject) == -2) {
759 $searchCategoryProjectSqlList[] = "NOT EXISTS (SELECT ck.fk_project FROM ".MAIN_DB_PREFIX."categorie_project as ck WHERE p.rowid = ck.fk_project)";
760 } elseif (intval($searchCategoryProject) > 0) {
761 if ($searchCategoryProjectOperator == 0) {
762 $searchCategoryProjectSqlList[] = " EXISTS (SELECT ck.fk_project FROM ".MAIN_DB_PREFIX."categorie_project as ck WHERE p.rowid = ck.fk_project AND ck.fk_categorie = ".((int) $searchCategoryProject).")";
763 } else {
764 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryProject);
765 }
766 }
767 }
768 if ($listofcategoryid) {
769 $searchCategoryProjectSqlList[] = " EXISTS (SELECT ck.fk_project FROM ".MAIN_DB_PREFIX."categorie_project as ck WHERE p.rowid = ck.fk_project AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
770 }
771 if ($searchCategoryProjectOperator == 1) {
772 if (!empty($searchCategoryProjectSqlList)) {
773 $sql .= " AND (".implode(' OR ', $searchCategoryProjectSqlList).")";
774 }
775 } else {
776 if (!empty($searchCategoryProjectSqlList)) {
777 $sql .= " AND (".implode(' AND ', $searchCategoryProjectSqlList).")";
778 }
779 }
780}
781$searchCategoryCustomerSqlList = array();
782if ($searchCategoryCustomerOperator == 1) {
783 $existsCategoryCustomerList = array();
784 foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
785 if (intval($searchCategoryCustomer) == -2) {
786 $sqlCategoryCustomerNotExists = " NOT EXISTS (";
787 $sqlCategoryCustomerNotExists .= " SELECT cat_cus.fk_soc";
788 $sqlCategoryCustomerNotExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
789 $sqlCategoryCustomerNotExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
790 $sqlCategoryCustomerNotExists .= " )";
791 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerNotExists;
792 } elseif (intval($searchCategoryCustomer) > 0) {
793 $existsCategoryCustomerList[] = $db->escape($searchCategoryCustomer);
794 }
795 }
796 if (!empty($existsCategoryCustomerList)) {
797 $sqlCategoryCustomerExists = " EXISTS (";
798 $sqlCategoryCustomerExists .= " SELECT cat_cus.fk_soc";
799 $sqlCategoryCustomerExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
800 $sqlCategoryCustomerExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
801 $sqlCategoryCustomerExists .= " AND cat_cus.fk_categorie IN (".$db->sanitize(implode(',', $existsCategoryCustomerList)).")";
802 $sqlCategoryCustomerExists .= " )";
803 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerExists;
804 }
805 if (!empty($searchCategoryCustomerSqlList)) {
806 $sql .= " AND (".implode(' OR ', $searchCategoryCustomerSqlList).")";
807 }
808} else {
809 foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
810 if (intval($searchCategoryCustomer) == -2) {
811 $sqlCategoryCustomerNotExists = " NOT EXISTS (";
812 $sqlCategoryCustomerNotExists .= " SELECT cat_cus.fk_soc";
813 $sqlCategoryCustomerNotExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
814 $sqlCategoryCustomerNotExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
815 $sqlCategoryCustomerNotExists .= " )";
816 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerNotExists;
817 } elseif (intval($searchCategoryCustomer) > 0) {
818 $searchCategoryCustomerSqlList[] = "p.fk_soc IN (SELECT fk_soc FROM ".$db->prefix()."categorie_societe WHERE fk_categorie = ".((int) $searchCategoryCustomer).")";
819 }
820 }
821 if (!empty($searchCategoryCustomerSqlList)) {
822 $sql .= " AND (".implode(' AND ', $searchCategoryCustomerSqlList).")";
823 }
824}
825// Add where from extra fields
826include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
827// Add where from hooks
828$parameters = array();
829$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
830$sql .= $hookmanager->resPrint;
831//print $sql;
832
833// Count total nb of records
834$nbtotalofrecords = '';
835if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
836 /* The fast and low memory method to get and count full list converts the sql into a sql count */
837 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
838 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
839 $resql = $db->query($sqlforcount);
840 if ($resql) {
841 $objforcount = $db->fetch_object($resql);
842 $nbtotalofrecords = $objforcount->nbtotalofrecords;
843 } else {
844 dol_print_error($db);
845 }
846
847 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
848 $page = 0;
849 $offset = 0;
850 }
851 $db->free($resql);
852}
853
854// Complete request and execute it with limit
855$sql .= $db->order($sortfield, $sortorder);
856if ($limit) {
857 $sql .= $db->plimit($limit + 1, $offset);
858}
859//print $sql;
860
861$resql = $db->query($sql);
862if (!$resql) {
863 dol_print_error($db);
864 exit;
865}
866
867$num = $db->num_rows($resql);
868
869// Direct jump if only one record found
870if ($num == 1 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
871 $obj = $db->fetch_object($resql);
872 header("Location: ".DOL_URL_ROOT.'/projet/card.php?id='.$obj->id);
873 exit;
874}
875
876
877// Output page
878// --------------------------------------------------------------------
879
880llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-project page-list');
881
882$arrayofselected = is_array($toselect) ? $toselect : array();
883
884$param = '';
885if (!empty($mode)) {
886 $param .= '&mode='.urlencode($mode);
887}
888if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
889 $param .= '&contextpage='.urlencode($contextpage);
890}
891if ($limit > 0 && $limit != $conf->liste_limit) {
892 $param .= '&limit='.((int) $limit);
893}
894if ($optioncss != '') {
895 $param .= '&optioncss='.urlencode($optioncss);
896}
897if ($search_all != '') {
898 $param .= '&search_all='.urlencode($search_all);
899}
900if ($search_entity != '') {
901 $param .= '&search_entity='.((int) $search_entity);
902}
903if ($groupby != '') {
904 $param .= '&groupby='.urlencode($groupby);
905}
906
907if ($socid) {
908 $param .= '&socid='.urlencode((string) $socid);
909}
910if ($search_sday) {
911 $param .= '&search_sday='.urlencode((string) ($search_sday));
912}
913if ($search_smonth) {
914 $param .= '&search_smonth='.urlencode((string) ($search_smonth));
915}
916if ($search_syear) {
917 $param .= '&search_syear='.urlencode((string) ($search_syear));
918}
919if ($search_eday) {
920 $param .= '&search_eday='.urlencode((string) ($search_eday));
921}
922if ($search_emonth) {
923 $param .= '&search_emonth='.urlencode((string) ($search_emonth));
924}
925if ($search_eyear) {
926 $param .= '&search_eyear='.urlencode((string) ($search_eyear));
927}
928if ($search_date_start_startmonth) {
929 $param .= '&search_date_start_startmonth='.urlencode((string) ($search_date_start_startmonth));
930}
931if ($search_date_start_startyear) {
932 $param .= '&search_date_start_startyear='.urlencode((string) ($search_date_start_startyear));
933}
934if ($search_date_start_startday) {
935 $param .= '&search_date_start_startday='.urlencode((string) ($search_date_start_startday));
936}
937if ($search_date_start_start) {
938 $param .= '&search_date_start_start='.urlencode($search_date_start_start);
939}
940if ($search_date_start_endmonth) {
941 $param .= '&search_date_start_endmonth='.urlencode((string) ($search_date_start_endmonth));
942}
943if ($search_date_start_endyear) {
944 $param .= '&search_date_start_endyear='.urlencode((string) ($search_date_start_endyear));
945}
946if ($search_date_start_endday) {
947 $param .= '&search_date_start_endday='.urlencode((string) ($search_date_start_endday));
948}
949if ($search_date_start_end) {
950 $param .= '&search_date_start_end='.urlencode($search_date_start_end);
951}
952if ($search_date_end_startmonth) {
953 $param .= '&search_date_end_startmonth='.urlencode((string) ($search_date_end_startmonth));
954}
955if ($search_date_end_startyear) {
956 $param .= '&search_date_end_startyear='.urlencode((string) ($search_date_end_startyear));
957}
958if ($search_date_end_startday) {
959 $param .= '&search_date_end_startday='.urlencode((string) ($search_date_end_startday));
960}
961if ($search_date_end_start) {
962 $param .= '&search_date_end_start='.urlencode($search_date_end_start);
963}
964if ($search_date_end_endmonth) {
965 $param .= '&search_date_end_endmonth='.urlencode((string) ($search_date_end_endmonth));
966}
967if ($search_date_end_endyear) {
968 $param .= '&search_date_end_endyear='.urlencode((string) ($search_date_end_endyear));
969}
970if ($search_date_end_endday) {
971 $param .= '&search_date_end_endday='.urlencode((string) ($search_date_end_endday));
972}
973if ($search_date_end_end) {
974 $param .= '&search_date_end_end=' . urlencode($search_date_end_end);
975}
976if ($search_date_creation_startmonth) {
977 $param .= '&search_date_creation_startmonth='.urlencode((string) ($search_date_creation_startmonth));
978}
979if ($search_date_creation_startyear) {
980 $param .= '&search_date_creation_startyear='.urlencode((string) ($search_date_creation_startyear));
981}
982if ($search_date_creation_startday) {
983 $param .= '&search_date_creation_startday='.urlencode((string) ($search_date_creation_startday));
984}
985if ($search_date_creation_start) {
986 $param .= '&search_date_creation_start='.urlencode($search_date_creation_start);
987}
988if ($search_date_creation_endmonth) {
989 $param .= '&search_date_creation_endmonth='.urlencode((string) ($search_date_creation_endmonth));
990}
991if ($search_date_creation_endyear) {
992 $param .= '&search_date_creation_endyear='.urlencode((string) ($search_date_creation_endyear));
993}
994if ($search_date_creation_endday) {
995 $param .= '&search_date_creation_endday='.urlencode((string) ($search_date_creation_endday));
996}
997if ($search_date_creation_end) {
998 $param .= '&search_date_creation_end='.urlencode($search_date_creation_end);
999}
1000if ($search_date_modif_startmonth) {
1001 $param .= '&search_date_modif_startmonth='.urlencode((string) ($search_date_modif_startmonth));
1002}
1003if ($search_date_modif_startyear) {
1004 $param .= '&search_date_modif_startyear='.urlencode((string) ($search_date_modif_startyear));
1005}
1006if ($search_date_modif_startday) {
1007 $param .= '&search_date_modif_startday='.urlencode((string) ($search_date_modif_startday));
1008}
1009if ($search_date_modif_start) {
1010 $param .= '&search_date_modif_start='.urlencode($search_date_modif_start);
1011}
1012if ($search_date_modif_endmonth) {
1013 $param .= '&search_date_modif_endmonth='.urlencode((string) ($search_date_modif_endmonth));
1014}
1015if ($search_date_modif_endyear) {
1016 $param .= '&search_date_modif_endyear='.urlencode((string) ($search_date_modif_endyear));
1017}
1018if ($search_date_modif_endday) {
1019 $param .= '&search_date_modif_endday='.urlencode((string) ($search_date_modif_endday));
1020}
1021if ($search_date_modif_end) {
1022 $param .= '&search_date_modif_end=' . urlencode($search_date_modif_end);
1023}
1024if (!empty($search_category_array)) {
1025 foreach ($search_category_array as $tmpval) {
1026 $param .= '&search_categegory_project_list[]='.urlencode($tmpval);
1027 }
1028}
1029if ($search_ref != '') {
1030 $param .= '&search_ref='.urlencode($search_ref);
1031}
1032if ($search_label != '') {
1033 $param .= '&search_label='.urlencode($search_label);
1034}
1035if ($search_societe != '') {
1036 $param .= '&search_societe='.urlencode($search_societe);
1037}
1038if ($search_societe_alias != '') {
1039 $param .= '&search_societe_alias='.urlencode($search_societe_alias);
1040}
1041if ($search_societe_country != '') {
1042 $param .= '&search_societe_country='.urlencode($search_societe_country);
1043}
1044if ($search_status != '' && $search_status != '-1') {
1045 $param .= "&search_status=".urlencode($search_status);
1046}
1047if ($search_option) {
1048 $param .= "&search_option=".urlencode($search_option);
1049}
1050if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'openedopp', 'notopenedopp', 'none'))) {
1051 $param .= '&search_opp_status='.urlencode($search_opp_status);
1052}
1053if ($search_opp_percent != '') {
1054 $param .= '&search_opp_percent='.urlencode($search_opp_percent);
1055}
1056if ($search_public != '') {
1057 $param .= '&search_public='.urlencode($search_public);
1058}
1059if ($search_project_user > 0) {
1060 $param .= '&search_project_user='.urlencode((string) $search_project_user);
1061}
1062if ($search_project_contact > 0) {
1063 $param .= '&search_project_contact='.urlencode((string) ($search_project_contact));
1064}
1065if ($search_sale > 0) {
1066 $param .= '&search_sale='.urlencode((string) ($search_sale));
1067}
1068if ($search_opp_amount != '') {
1069 $param .= '&search_opp_amount='.urlencode($search_opp_amount);
1070}
1071if ($search_budget_amount != '') {
1072 $param .= '&search_budget_amount='.urlencode($search_budget_amount);
1073}
1074if ($search_usage_task != '') {
1075 $param .= '&search_usage_task='.urlencode($search_usage_task);
1076}
1077if ($search_usage_bill_time != '') {
1078 $param .= '&search_usage_opportunity='.urlencode($search_usage_bill_time);
1079}
1080if ($search_usage_event_organization != '') {
1081 $param .= '&search_usage_event_organization='.urlencode($search_usage_event_organization);
1082}
1083if ($search_accept_conference_suggestions != '') {
1084 $param .= '&search_accept_conference_suggestions='.urlencode($search_accept_conference_suggestions);
1085}
1086if ($search_accept_booth_suggestions != '') {
1087 $param .= '&search_accept_booth_suggestions='.urlencode($search_accept_booth_suggestions);
1088}
1089if ($search_price_registration != '') {
1090 $param .= '&search_price_registration='.urlencode($search_price_registration);
1091}
1092if ($search_price_booth != '') {
1093 $param .= '&search_price_booth='.urlencode($search_price_booth);
1094}
1095if ($search_login) {
1096 $param .= '&search_login='.urlencode($search_login);
1097}
1098if ($search_import_key) {
1099 $param .= '&search_import_key='.urlencode($search_import_key);
1100}
1101foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
1102 $param .= "&search_category_customer_list[]=".urlencode($searchCategoryCustomer);
1103}
1104// Add $param from extra fields
1105include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
1106
1107// Add $param from hooks
1108$parameters = array('param' => &$param);
1109$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1110$param .= $hookmanager->resPrint;
1111
1112// List of mass actions available
1113$arrayofmassactions = array(
1114 'validate' => img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
1115 'generate_doc' => img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
1116 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
1117 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
1118);
1119//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
1120if ($user->hasRight('projet', 'creer')) {
1121 $arrayofmassactions['close'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Close");
1122 $arrayofmassactions['preaffectuser'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("AffectUser");
1123}
1124if ($user->hasRight('projet', 'supprimer')) {
1125 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
1126}
1127if (isModEnabled('category') && $user->hasRight('projet', 'creer')) {
1128 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
1129}
1130if (in_array($massaction, array('presend', 'predelete', 'preaffecttag', 'preaffectuser'))) {
1131 $arrayofmassactions = array();
1132}
1133
1134$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
1135
1136$url = DOL_URL_ROOT.'/projet/card.php?action=create';
1137if (!empty($socid)) {
1138 $url .= '&socid='.$socid;
1139}
1140if ($search_usage_event_organization == 1) {
1141 $url .= '&usage_organize_event=1';
1142 if (((int) $search_usage_opportunity) < 1) {
1143 $url .= '&usage_opportunity=0';
1144 }
1145}
1146
1147$newcardbutton = '';
1148$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
1149$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
1150$newcardbutton .= dolGetButtonTitleSeparator();
1151$newcardbutton .= dolGetButtonTitle($langs->trans('NewProject'), '', 'fa fa-plus-circle', $url, '', $user->hasRight('projet', 'creer'));
1152
1153print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
1154if ($optioncss != '') {
1155 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
1156}
1157print '<input type="hidden" name="token" value="'.newToken().'">';
1158print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
1159print '<input type="hidden" name="action" value="list">';
1160print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
1161print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
1162print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
1163print '<input type="hidden" name="mode" value="'.$mode.'">';
1164print '<input type="hidden" name="groupby" value="'.$groupby.'">';
1165
1166// Show description of content
1167$htmltooltip = '';
1168if ($search_project_user == $user->id) {
1169 $htmltooltip .= $langs->trans("MyProjectsDesc");
1170} else {
1171 if ($user->hasRight('projet', 'all', 'lire') && !$socid) {
1172 $htmltooltip .= $langs->trans("ProjectsDesc");
1173 } else {
1174 $htmltooltip .= $langs->trans("ProjectsPublicDesc");
1175 }
1176}
1177
1178print_barre_liste($form->textwithpicto($title, $htmltooltip), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'project', 0, $newcardbutton, '', $limit, 0, 0, 1);
1179
1180
1181$topicmail = "Information";
1182$modelmail = "project";
1183$objecttmp = new Project($db);
1184$trackid = 'proj'.$object->id;
1185include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
1186
1187if ($search_all) {
1188 foreach ($fieldstosearchall as $key => $val) {
1189 $fieldstosearchall[$key] = $langs->trans($val);
1190 }
1191 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
1192}
1193
1194$moreforfilter = '';
1195
1196// If the user can view user other than himself
1197$moreforfilter .= '<div class="divsearchfield">';
1198$tmptitle = $langs->trans('ProjectsWithThisUserAsContact');
1199//$includeonly = 'hierarchyme';
1200$includeonly = '';
1201if (!$user->hasRight('user', 'user', 'lire')) {
1202 $includeonly = array($user->id);
1203}
1204$moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', $tmptitle, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
1205$moreforfilter .= '</div>';
1206
1207$moreforfilter .= '<div class="divsearchfield">';
1208$tmptitle = $langs->trans('ProjectsWithThisContact');
1209$moreforfilter .= img_picto($tmptitle, 'contact', 'class="pictofixedwidth"').$form->select_contact(0, $search_project_contact ? $search_project_contact : '', 'search_project_contact', $tmptitle, '', '', 0, 'maxwidth300 widthcentpercentminusx');
1210
1211$moreforfilter .= '</div>';
1212
1213// If the user can view thirdparties other than his'
1214if ($user->hasRight('user', 'user', 'lire')) {
1215 $langs->load("commercial");
1216 $moreforfilter .= '<div class="divsearchfield">';
1217 $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative');
1218 $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth300 widthcentpercentminusx');
1219 $moreforfilter .= '</div>';
1220}
1221
1222// Filter on categories
1223if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
1224 $formcategory = new FormCategory($db);
1225 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PROJECT, $search_category_array, 'minwidth300imp minwidth300 widthcentpercentminusx');
1226}
1227
1228// Filter on customer categories
1229if (getDolGlobalString('MAIN_SEARCH_CATEGORY_CUSTOMER_ON_PROJECT_LIST') && isModEnabled("category") && $user->hasRight('categorie', 'lire')) {
1230 $formcategory = new FormCategory($db);
1231 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_CUSTOMER, $searchCategoryCustomerList, 'minwidth300', $searchCategoryCustomerList ? $searchCategoryCustomerList : 0);
1232}
1233
1234// alert on late date
1235$moreforfilter .= '<div class="divsearchfield">';
1236$moreforfilter .= '<label for="search_option" title="'.$langs->trans("Late").'">'.$langs->trans('Alert').' </label><input type="checkbox" id="search_option" name="search_option" value="late"'.($search_option == 'late' ? ' checked' : '').'>';
1237$moreforfilter .= '</div>';
1238
1239if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1240 //Checkbox for omitting child projects filter
1241 $moreforfilter .= '<p style="display: inline-block; margin-left: 5px;">'.$langs->trans("Omit sub-projects").' </p><input type="checkbox" style="margin-left: 10px" class="valignmiddle" id="search_omitChildren" name="search_omitChildren"'.($search_omitChildren ? ' checked="checked"' : '').'"> ';
1242}
1243
1244if (!empty($moreforfilter)) {
1245 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1246 print $moreforfilter;
1247 $parameters = array();
1248 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1249 print $hookmanager->resPrint;
1250 print '</div>';
1251}
1252
1253$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
1254$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup
1255$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
1256$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
1257
1258
1259print '<div class="div-table-responsive">';
1260print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
1261
1262// Fields title search
1263// --------------------------------------------------------------------
1264print '<tr class="liste_titre_filter">';
1265// Action column
1266if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1267 print '<td class="liste_titre maxwidthsearch">';
1268 $searchpicto = $form->showFilterButtons('left');
1269 print $searchpicto;
1270 print '</td>';
1271}
1272// Project ref
1273if (!empty($arrayfields['p.ref']['checked'])) {
1274 print '<td class="liste_titre">';
1275 print '<input type="text" class="flat" name="search_ref" value="'.dol_escape_htmltag($search_ref).'" size="6">';
1276 print '</td>';
1277}
1278// Project label
1279if (!empty($arrayfields['p.title']['checked'])) {
1280 print '<td class="liste_titre">';
1281 print '<input type="text" class="flat" name="search_label" size="8" value="'.dol_escape_htmltag($search_label).'">';
1282 print '</td>';
1283}
1284// Third party
1285if (!empty($arrayfields['s.nom']['checked'])) {
1286 print '<td class="liste_titre">';
1287 if ($socid > 0) {
1288 $tmpthirdparty = new Societe($db);
1289 $tmpthirdparty->fetch($socid);
1290 $search_societe = $tmpthirdparty->name;
1291 }
1292 print '<input type="text" class="flat" name="search_societe" size="8" value="'.dol_escape_htmltag($search_societe).'">';
1293 print '</td>';
1294}
1295
1296// Alias
1297if (!empty($arrayfields['s.name_alias']['checked'])) {
1298 print '<td class="liste_titre">';
1299 if ($socid > 0) {
1300 $tmpthirdparty = new Societe($db);
1301 $tmpthirdparty->fetch($socid);
1302 $search_societe_alias = $tmpthirdparty->name_alias;
1303 }
1304 print '<input type="text" class="flat" name="search_societe_alias" size="8" value="'.dol_escape_htmltag($search_societe_alias).'">';
1305 print '</td>';
1306}
1307// Country of thirdparty
1308if (!empty($arrayfields['co.country_code']['checked'])) {
1309 print '<td class="liste_titre">';
1310 print '<input type="text" class="flat width50" name="search_societe_country" value="'.dol_escape_htmltag($search_societe_country).'">';
1311 print '</td>';
1312}
1313// Sale representative
1314if (!empty($arrayfields['commercial']['checked'])) {
1315 print '<td class="liste_titre">&nbsp;</td>';
1316}
1317// Start date
1318if (!empty($arrayfields['p.dateo']['checked'])) {
1319 print '<td class="liste_titre center">';
1320 print '<div class="nowrapfordate">';
1321 print $form->selectDate($search_date_start_start ? $search_date_start_start : -1, 'search_date_start_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1322 print '</div>';
1323 print '<div class="nowrapfordate">';
1324 print $form->selectDate($search_date_start_end ? $search_date_start_end : -1, 'search_date_start_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1325 print '</div>';
1326 print '</td>';
1327}
1328// End date
1329if (!empty($arrayfields['p.datee']['checked'])) {
1330 print '<td class="liste_titre center">';
1331 print '<div class="nowrapfordate">';
1332 print $form->selectDate($search_date_end_start ? $search_date_end_start : -1, 'search_date_end_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1333 print '</div>';
1334 print '<div class="nowrapfordate">';
1335 print $form->selectDate($search_date_end_end ? $search_date_end_end : -1, 'search_date_end_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1336 print '</div>';
1337 print '</td>';
1338}
1339// Visibility
1340if (!empty($arrayfields['p.public']['checked'])) {
1341 print '<td class="liste_titre center">';
1342 $array = array('' => '', 0 => $langs->trans("PrivateProject"), 1 => $langs->trans("SharedProject"));
1343 print $form->selectarray('search_public', $array, $search_public, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth75');
1344 print '</td>';
1345}
1346if (!empty($arrayfields['c.assigned']['checked'])) {
1347 print '<td class="liste_titre center">';
1348 print '</td>';
1349}
1350// Opp status
1351if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
1352 print '<td class="liste_titre nowrap center">';
1353 print $formproject->selectOpportunityStatus('search_opp_status', $search_opp_status, 1, 1, 1, 0, 'maxwidth125 nowrapoption', 1, 1);
1354 print '</td>';
1355}
1356if (!empty($arrayfields['p.opp_amount']['checked'])) {
1357 print '<td class="liste_titre nowrap right">';
1358 print '<input type="text" class="flat" name="search_opp_amount" size="3" value="'.$search_opp_amount.'">';
1359 print '</td>';
1360}
1361if (!empty($arrayfields['p.opp_percent']['checked'])) {
1362 print '<td class="liste_titre nowrap right">';
1363 print '<input type="text" class="flat" name="search_opp_percent" size="2" value="'.$search_opp_percent.'">';
1364 print '</td>';
1365}
1366if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
1367 print '<td class="liste_titre nowrap right">';
1368 print '</td>';
1369}
1370if (!empty($arrayfields['p.budget_amount']['checked'])) {
1371 print '<td class="liste_titre nowrap right">';
1372 print '<input type="text" class="flat" name="search_budget_amount" size="4" value="'.$search_budget_amount.'">';
1373 print '</td>';
1374}
1375if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
1376 print '<td class="liste_titre nowrap">';
1377 print $form->selectyesno('search_usage_opportunity', $search_usage_opportunity, 1, false, 1, 1);
1378 print '';
1379 print '</td>';
1380}
1381if (!empty($arrayfields['p.usage_task']['checked'])) {
1382 print '<td class="liste_titre nowrap">';
1383 print $form->selectyesno('search_usage_task', $search_usage_task, 1, false, 1, 1);
1384 print '</td>';
1385}
1386if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
1387 print '<td class="liste_titre nowrap">';
1388 print $form->selectyesno('search_usage_bill_time', $search_usage_bill_time, 1, false, 1, 1);
1389 print '</td>';
1390}
1391if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
1392 print '<td class="liste_titre nowrap">';
1393 print $form->selectyesno('search_usage_event_organization', $search_usage_event_organization, 1, false, 1, 1);
1394 print '</td>';
1395}
1396if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
1397 print '<td class="liste_titre nowrap">';
1398 print $form->selectyesno('search_accept_conference_suggestions', $search_accept_conference_suggestions, 1, false, 1, 1);
1399 print '</td>';
1400}
1401if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
1402 print '<td class="liste_titre nowrap">';
1403 print $form->selectyesno('search_accept_booth_suggestions', $search_accept_booth_suggestions, 1, false, 1, 1);
1404 print '</td>';
1405}
1406if (!empty($arrayfields['p.price_registration']['checked'])) {
1407 print '<td class="liste_titre nowrap right">';
1408 print '<input type="text" class="flat" name="search_price_registration" size="4" value="'.dol_escape_htmltag($search_price_registration).'">';
1409 print '</td>';
1410}
1411if (!empty($arrayfields['p.price_booth']['checked'])) {
1412 print '<td class="liste_titre nowrap right">';
1413 print '<input type="text" class="flat" name="search_price_booth" size="4" value="'.dol_escape_htmltag($search_price_booth).'">';
1414 print '</td>';
1415}
1416if (!empty($arrayfields['u.login']['checked'])) {
1417 // Author
1418 print '<td class="liste_titre" align="center">';
1419 print '<input class="flat" size="4" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'">';
1420 print '</td>';
1421}
1422// Extra fields
1423include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1424
1425// Fields from hook
1426$parameters = array('arrayfields' => $arrayfields);
1427$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
1428print $hookmanager->resPrint;
1429// Creation date
1430if (!empty($arrayfields['p.datec']['checked'])) {
1431 print '<td class="liste_titre center">';
1432 print '<div class="nowrapfordate">';
1433 print $form->selectDate($search_date_creation_start ? $search_date_creation_start : -1, 'search_date_creation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1434 print '</div>';
1435 print '<div class="nowrapfordate">';
1436 print $form->selectDate($search_date_creation_end ? $search_date_creation_end : -1, 'search_date_creation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1437 print '</div>';
1438 print '</td>';
1439}
1440// Modification date
1441if (!empty($arrayfields['p.tms']['checked'])) {
1442 print '<td class="liste_titre center">';
1443 print '<div class="nowrapfordate">';
1444 print $form->selectDate($search_date_modif_start ? $search_date_modif_start : -1, 'search_date_modif_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1445 print '</div>';
1446 print '<div class="nowrapfordate">';
1447 print $form->selectDate($search_date_modif_end ? $search_date_modif_end : -1, 'search_date_modif_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1448 print '</div>';
1449 print '</td>';
1450}
1451if (!empty($arrayfields['p.email_msgid']['checked'])) {
1452 // Email msg id
1453 print '<td class="liste_titre">';
1454 print '</td>';
1455}
1456if (!empty($arrayfields['p.import_key']['checked'])) {
1457 // Import key
1458 print '<td class="liste_titre">';
1459 print '<input class="flat width75" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
1460 print '</td>';
1461}
1462if (!empty($arrayfields['p.fk_statut']['checked'])) {
1463 print '<td class="liste_titre center parentonrightofpage">';
1464 $formproject->selectProjectsStatus($search_status, 1, 'search_status');
1465 print '</td>';
1466}
1467// Action column
1468if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1469 print '<td class="liste_titre maxwidthsearch">';
1470 $searchpicto = $form->showFilterButtons();
1471 print $searchpicto;
1472 print '</td>';
1473}
1474print '</tr>'."\n";
1475
1476$totalarray = array();
1477$totalarray['nbfield'] = 0;
1478
1479// Fields title label
1480// --------------------------------------------------------------------
1481print '<tr class="liste_titre">';
1482if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1483 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1484 $totalarray['nbfield']++;
1485}
1486if (!empty($arrayfields['p.ref']['checked'])) {
1487 print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
1488 $totalarray['nbfield']++;
1489}
1490if (!empty($arrayfields['p.title']['checked'])) {
1491 print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER["PHP_SELF"], "p.title", "", $param, "", $sortfield, $sortorder);
1492 $totalarray['nbfield']++;
1493}
1494if (!empty($arrayfields['s.nom']['checked'])) {
1495 print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder);
1496 $totalarray['nbfield']++;
1497}
1498if (!empty($arrayfields['s.name_alias']['checked'])) {
1499 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1500 print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER["PHP_SELF"], "s.name_alias", "", $param, "", $sortfield, $sortorder);
1501 $totalarray['nbfield']++;
1502}
1503if (!empty($arrayfields['co.country_code']['checked'])) {
1504 print_liste_field_titre($arrayfields['co.country_code']['label'], $_SERVER["PHP_SELF"], "country.code", "", $param, "", $sortfield, $sortorder, 'center ');
1505 $totalarray['nbfield']++;
1506}
1507if (!empty($arrayfields['commercial']['checked'])) {
1508 print_liste_field_titre($arrayfields['commercial']['label'], $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder, 'tdoverflowmax100imp ');
1509 $totalarray['nbfield']++;
1510}
1511if (!empty($arrayfields['p.dateo']['checked'])) {
1512 print_liste_field_titre($arrayfields['p.dateo']['label'], $_SERVER["PHP_SELF"], "p.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
1513 $totalarray['nbfield']++;
1514}
1515if (!empty($arrayfields['p.datee']['checked'])) {
1516 print_liste_field_titre($arrayfields['p.datee']['label'], $_SERVER["PHP_SELF"], "p.datee", "", $param, '', $sortfield, $sortorder, 'center ');
1517 $totalarray['nbfield']++;
1518}
1519if (!empty($arrayfields['p.public']['checked'])) {
1520 print_liste_field_titre($arrayfields['p.public']['label'], $_SERVER["PHP_SELF"], "p.public", "", $param, "", $sortfield, $sortorder, 'center ');
1521 $totalarray['nbfield']++;
1522}
1523if (!empty($arrayfields['c.assigned']['checked'])) {
1524 print_liste_field_titre($arrayfields['c.assigned']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '');
1525 $totalarray['nbfield']++;
1526}
1527if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
1528 print_liste_field_titre($arrayfields['p.fk_opp_status']['label'], $_SERVER["PHP_SELF"], 'p.fk_opp_status', "", $param, '', $sortfield, $sortorder, 'center ');
1529 $totalarray['nbfield']++;
1530}
1531if (!empty($arrayfields['p.opp_amount']['checked'])) {
1532 print_liste_field_titre($arrayfields['p.opp_amount']['label'], $_SERVER["PHP_SELF"], 'p.opp_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1533 $totalarray['nbfield']++;
1534}
1535if (!empty($arrayfields['p.opp_percent']['checked'])) {
1536 print_liste_field_titre($arrayfields['p.opp_percent']['label'], $_SERVER['PHP_SELF'], 'p.opp_percent', "", $param, '', $sortfield, $sortorder, 'right ');
1537 $totalarray['nbfield']++;
1538}
1539if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
1540 print_liste_field_titre($arrayfields['opp_weighted_amount']['label'], $_SERVER['PHP_SELF'], 'opp_weighted_amount', '', $param, '', $sortfield, $sortorder, 'right ');
1541 $totalarray['nbfield']++;
1542}
1543if (!empty($arrayfields['p.budget_amount']['checked'])) {
1544 print_liste_field_titre($arrayfields['p.budget_amount']['label'], $_SERVER["PHP_SELF"], 'p.budget_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1545 $totalarray['nbfield']++;
1546}
1547if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
1548 print_liste_field_titre($arrayfields['p.usage_opportunity']['label'], $_SERVER["PHP_SELF"], 'p.usage_opportunity', "", $param, '', $sortfield, $sortorder, '');
1549 $totalarray['nbfield']++;
1550}
1551if (!empty($arrayfields['p.usage_task']['checked'])) {
1552 print_liste_field_titre($arrayfields['p.usage_task']['label'], $_SERVER["PHP_SELF"], 'p.usage_task', "", $param, '', $sortfield, $sortorder, '');
1553 $totalarray['nbfield']++;
1554}
1555if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
1556 print_liste_field_titre($arrayfields['p.usage_bill_time']['label'], $_SERVER["PHP_SELF"], 'p.usage_bill_time', "", $param, '', $sortfield, $sortorder, '');
1557 $totalarray['nbfield']++;
1558}
1559if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
1560 print_liste_field_titre($arrayfields['p.usage_organize_event']['label'], $_SERVER["PHP_SELF"], 'p.usage_organize_event', "", $param, '', $sortfield, $sortorder, '');
1561 $totalarray['nbfield']++;
1562}
1563if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
1564 print_liste_field_titre($arrayfields['p.accept_conference_suggestions']['label'], $_SERVER["PHP_SELF"], 'p.accept_conference_suggestions', "", $param, '', $sortfield, $sortorder, '');
1565 $totalarray['nbfield']++;
1566}
1567if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
1568 print_liste_field_titre($arrayfields['p.accept_booth_suggestions']['label'], $_SERVER["PHP_SELF"], 'p.accept_booth_suggestions', "", $param, '', $sortfield, $sortorder, '');
1569 $totalarray['nbfield']++;
1570}
1571if (!empty($arrayfields['p.price_registration']['checked'])) {
1572 print_liste_field_titre($arrayfields['p.price_registration']['label'], $_SERVER["PHP_SELF"], 'p.price_registration', "", $param, '', $sortfield, $sortorder, 'right ');
1573 $totalarray['nbfield']++;
1574}
1575if (!empty($arrayfields['p.price_booth']['checked'])) {
1576 print_liste_field_titre($arrayfields['p.price_booth']['label'], $_SERVER["PHP_SELF"], 'p.price_booth', "", $param, '', $sortfield, $sortorder, 'right ');
1577 $totalarray['nbfield']++;
1578}
1579if (!empty($arrayfields['u.login']['checked'])) {
1580 print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder);
1581 $totalarray['nbfield']++;
1582}
1583// Extra fields
1584include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1585// Hook fields
1586$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
1587$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1588print $hookmanager->resPrint;
1589if (!empty($arrayfields['p.datec']['checked'])) {
1590 print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1591 $totalarray['nbfield']++;
1592}
1593if (!empty($arrayfields['p.tms']['checked'])) {
1594 print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1595 $totalarray['nbfield']++;
1596}
1597if (!empty($arrayfields['p.email_msgid']['checked'])) {
1598 print_liste_field_titre($arrayfields['p.email_msgid']['label'], $_SERVER["PHP_SELF"], "p.email_msgid", "", $param, '', $sortfield, $sortorder, 'center ');
1599 $totalarray['nbfield']++;
1600}
1601if (!empty($arrayfields['p.import_key']['checked'])) {
1602 print_liste_field_titre($arrayfields['p.import_key']['label'], $_SERVER["PHP_SELF"], "p.import_key", "", $param, '', $sortfield, $sortorder, '');
1603 $totalarray['nbfield']++;
1604}
1605if (!empty($arrayfields['p.fk_statut']['checked'])) {
1606 print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'center ');
1607 $totalarray['nbfield']++;
1608}
1609// Action column
1610if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1611 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1612 $totalarray['nbfield']++;
1613}
1614print '</tr>'."\n";
1615
1616
1617$i = 0;
1618$savnbfield = $totalarray['nbfield'];
1619$totalarray = array(
1620 'nbfield' => 0,
1621 'val' => array()
1622);
1623$imaxinloop = ($limit ? min($num, $limit) : $num);
1624while ($i < $imaxinloop) {
1625 $obj = $db->fetch_object($resql);
1626 if (empty($obj)) {
1627 break; // Should not happen
1628 }
1629
1630 // Thirdparty
1631 $companystatic->id = $obj->socid;
1632 $companystatic->name = $obj->name;
1633 $companystatic->name_alias = $obj->alias;
1634 $companystatic->client = $obj->client;
1635 $companystatic->code_client = $obj->code_client;
1636 $companystatic->email = $obj->email;
1637 $companystatic->phone = $obj->phone;
1638 $companystatic->address = $obj->address;
1639 $companystatic->zip = $obj->zip;
1640 $companystatic->town = $obj->town;
1641 $companystatic->country_code = $obj->country_code;
1642
1643 // Project
1644 $object->id = $obj->id;
1645 $object->ref = $obj->ref;
1646 $object->title = $obj->title;
1647 $object->fk_opp_status = $obj->fk_opp_status;
1648 $object->user_author_id = $obj->fk_user_creat;
1649 $object->date_creation = $db->jdate($obj->date_creation);
1650 $object->date_start = $db->jdate($obj->date_start);
1651 $object->date_end = $db->jdate($obj->date_end);
1652 $object->statut = $obj->status; // deprecated
1653 $object->status = $obj->status;
1654 $object->public = $obj->public;
1655 $object->opp_percent = $obj->opp_percent;
1656 $object->opp_status = $obj->fk_opp_status;
1657 $object->opp_status_code = $obj->opp_status_code;
1658 $object->opp_amount = !empty($obj->opp_amount) ? $obj->opp_amount : "";
1659 $object->opp_weighted_amount = $obj->opp_weighted_amount;
1660 $object->budget_amount = $obj->budget_amount;
1661 $object->usage_opportunity = $obj->usage_opportunity;
1662 $object->usage_task = $obj->usage_task;
1663 $object->usage_bill_time = $obj->usage_bill_time;
1664 $object->usage_organize_event = $obj->usage_organize_event;
1665 $object->email_msgid = $obj->email_msgid;
1666 $object->import_key = $obj->import_key;
1667 $object->thirdparty = $companystatic;
1668
1669 //$userAccess = $object->restrictedProjectArea($user); // disabled, permission on project must be done by the select
1670
1671 $stringassignedusers = '';
1672
1673 if (!empty($arrayfields['c.assigned']['checked'])) {
1674 $ifisrt = 1;
1675 foreach (array('internal', 'external') as $source) {
1676 $tab = $object->liste_contact(-1, $source, 0, '', 1);
1677 $numcontact = count($tab);
1678 if (!empty($numcontact)) {
1679 foreach ($tab as $contactproject) {
1680 //var_dump($contacttask);
1681 if ($source == 'internal') {
1682 if (!empty($conf->cache['user'][$contactproject['id']])) {
1683 $c = $conf->cache['user'][$contactproject['id']];
1684 } else {
1685 $c = new User($db);
1686 $c->fetch($contactproject['id']);
1687 $conf->cache['user'][$contactproject['id']] = $c;
1688 }
1689 } else {
1690 if (!empty($conf->cache['contact'][$contactproject['id']])) {
1691 $c = $conf->cache['contact'][$contactproject['id']];
1692 } else {
1693 $c = new Contact($db);
1694 $c->fetch($contactproject['id']);
1695 $conf->cache['contact'][$contactproject['id']] = $c;
1696 }
1697 }
1698 if (get_class($c) == 'User') {
1699 $stringassignedusers .= $c->getNomUrl(-2, '', 0, 0, 24, 1, '', 'valignmiddle'.($ifisrt ? '' : ' notfirst'));
1700 } else {
1701 $stringassignedusers .= $c->getNomUrl(-2, '', 0, 0, -1, 0, 'valignmiddle'.($ifisrt ? '' : ' notfirst'));
1702 }
1703 $ifisrt = 0;
1704 }
1705 }
1706 }
1707 }
1708
1709 if ($mode == 'kanban') {
1710 if ($i == 0) {
1711 print '<tr class="trkanban'.(empty($groupby) ? '' : ' trkanbangroupby').'"><td colspan="'.$savnbfield.'">';
1712 }
1713
1714 $groupbyvalue = 'unset';
1715 $groupbyfield = 'unsetfield';
1716 if (!empty($groupby)) {
1717 if (is_null($groupbyold)) {
1718 print '<div class="box-flex-container-columns kanban">'; // Start div for all kanban columns
1719 }
1720 // Start kanban column
1721 if (is_null($obj->$groupbyfield)) {
1722 $groupbyvalue = 'undefined';
1723 } else {
1724 $groupbyvalue = $obj->$groupbyfield;
1725 }
1726 if ($groupbyold !== $groupbyvalue) {
1727 if (!is_null($groupbyold)) {
1728 print '</div>'; // We need a new kanban column - end box-flex-container
1729 }
1730 foreach ($groupbyvalues as $tmpcursor => $tmpgroupbyvalue) {
1731 //var_dump("tmpcursor=".$tmpcursor." groupbyold=".$groupbyold." groupbyvalue=".$groupbyvalue);
1732 if (!is_null($groupbyold) && ($tmpcursor <= $groupbyold)) {
1733 continue;
1734 }
1735 if ($tmpcursor >= $groupbyvalue) {
1736 continue;
1737 }
1738 // We found a possible column with no value, we output the empty column
1739 print '<div class="box-flex-container-column kanban column';
1740 if (in_array($tmpcursor, $groupofcollpasedvalues)) {
1741 print ' kanbancollapsed';
1742 }
1743 print '" data-groupbyid="'.preg_replace('/[^a-z0-9]/', '', $tmpcursor).'">';
1744 print '<div class="kanbanlabel">'.$langs->trans($tmpgroupbyvalue).'</div>';
1745 print '</div>'; // Start and end the new column
1746 }
1747 print '<div class="box-flex-container-column kanban column" data-groupbyid="'.preg_replace('/[^a-z0-9]/', '', $groupbyvalue).'">'; // Start new column
1748 print '<div class="kanbanlabel">'.$langs->trans(empty($groupbyvalues[$groupbyvalue]) ? 'Undefined' : $groupbyvalues[$groupbyvalue]).'</div>';
1749 }
1750 $groupbyold = $groupbyvalue;
1751 } elseif ($i == 0) {
1752 print '<div class="box-flex-container kanban">';
1753 }
1754
1755 // Output Kanban
1756 $selected = -1;
1757 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1758 $selected = 0;
1759 if (in_array($object->id, $arrayofselected)) {
1760 $selected = 1;
1761 }
1762 }
1763 $arrayofdata = array('assignedusers' => $stringassignedusers, 'thirdparty' => $companystatic, 'selected' => $selected);
1764
1765 print $object->getKanbanView('', $arrayofdata, ($groupby ? 'small' : ''));
1766
1767 // if no more elements to show
1768 if ($i == ($imaxinloop - 1)) {
1769 // Close kanban column
1770 if (!empty($groupby)) {
1771 print '</div>'; // end box-flex-container
1772 foreach ($groupbyvalues as $tmpcursor => $tmpgroupbyvalue) {
1773 //var_dump("tmpcursor=".$tmpcursor." groupbyold=".$groupbyold." groupbyvalue=".$groupbyvalue);
1774 if ($tmpcursor <= $groupbyvalue) {
1775 continue;
1776 }
1777 // We found a possible column with no value, we output the empty column
1778 print '<div class="box-flex-container-column kanban column';
1779 if (in_array($tmpcursor, $groupofcollpasedvalues)) {
1780 print ' kanbancollapsed';
1781 }
1782 print '" data-groupbyid="'.preg_replace('/[^a-z0-9]/', '', $tmpcursor).'">';
1783 print '<div class="kanbanlabel">'.$langs->trans(empty($tmpgroupbyvalue) ? 'Undefined' : $tmpgroupbyvalue).'</div>';
1784 print '</div>'; // Start and end the new column
1785 }
1786 print '</div>'; // end box-flex-container-columns
1787 } else {
1788 print '</div>'; // end box-flex-container
1789 }
1790
1791 print '</td></tr>';
1792 }
1793 } else {
1794 // Author
1795 $userstatic->id = $obj->fk_user_creat;
1796 $userstatic->login = $obj->login;
1797 $userstatic->lastname = $obj->lastname;
1798 $userstatic->firstname = $obj->firstname;
1799 $userstatic->email = $obj->user_email;
1800 $userstatic->status = $obj->user_statut;
1801 $userstatic->entity = $obj->entity;
1802 $userstatic->photo = $obj->photo;
1803 $userstatic->office_phone = $obj->office_phone;
1804 $userstatic->office_fax = $obj->office_fax;
1805 $userstatic->user_mobile = $obj->user_mobile;
1806 $userstatic->job = $obj->job;
1807 $userstatic->gender = $obj->gender;
1808
1809 // Show here line of result
1810 $j = 0;
1811 print '<tr data-rowid="'.$object->id.'" class="oddeven '.((getDolGlobalInt('MAIN_FINISHED_LINES_OPACITY') == 1 && $object->status > 1) ? 'opacitymedium' : '').'">';
1812 // Action column
1813 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1814 print '<td class="nowrap center">';
1815 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1816 $selected = 0;
1817 if (in_array($object->id, $arrayofselected)) {
1818 $selected = 1;
1819 }
1820 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1821 }
1822 print '</td>';
1823 if (!$i) {
1824 $totalarray['nbfield']++;
1825 }
1826 }
1827 // Project url
1828 if (!empty($arrayfields['p.ref']['checked'])) {
1829 print '<td class="nowraponall tdoverflowmax200">';
1830 print $object->getNomUrl(1, (!empty(GETPOSTINT('search_usage_event_organization')) ? 'eventorganization' : ''));
1831 if ($object->hasDelay()) {
1832 print img_warning($langs->trans('Late'));
1833 }
1834 print '</td>';
1835 if (!$i) {
1836 $totalarray['nbfield']++;
1837 }
1838 }
1839 // Title
1840 if (!empty($arrayfields['p.title']['checked'])) {
1841 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($obj->title).'">';
1842 print dol_escape_htmltag($obj->title);
1843 print '</td>';
1844 if (!$i) {
1845 $totalarray['nbfield']++;
1846 }
1847 }
1848 // Company
1849 if (!empty($arrayfields['s.nom']['checked'])) {
1850 print '<td class="tdoverflowmax125">';
1851 if ($obj->socid) {
1852 print $companystatic->getNomUrl(1, '', 0, 0, -1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1);
1853 } else {
1854 print '&nbsp;';
1855 }
1856 print '</td>';
1857 if (!$i) {
1858 $totalarray['nbfield']++;
1859 }
1860 }
1861 // Alias
1862 if (!empty($arrayfields['s.name_alias']['checked'])) {
1863 print '<td class="tdoverflowmax100">';
1864 if ($obj->socid) {
1865 print $companystatic->name_alias;
1866 } else {
1867 print '&nbsp;';
1868 }
1869 print '</td>';
1870 if (!$i) {
1871 $totalarray['nbfield']++;
1872 }
1873 }
1874 // Country code
1875 if (!empty($arrayfields['co.country_code']['checked'])) {
1876 print '<td class="tdoverflowmax125 center">';
1877 print $obj->country_code;
1878 print '</td>';
1879 if (!$i) {
1880 $totalarray['nbfield']++;
1881 }
1882 }
1883 // Sales Representatives
1884 if (!empty($arrayfields['commercial']['checked'])) {
1885 print '<td class="tdoverflowmax150">';
1886 if ($obj->socid) {
1887 $companystatic->id = $obj->socid;
1888 $companystatic->name = $obj->name;
1889 $listsalesrepresentatives = $companystatic->getSalesRepresentatives($user);
1890 $nbofsalesrepresentative = count($listsalesrepresentatives);
1891 if ($nbofsalesrepresentative > 6) {
1892 // We print only number
1893 print $nbofsalesrepresentative;
1894 } elseif ($nbofsalesrepresentative > 0) {
1895 $userstatic = new User($db);
1896 $j = 0;
1897 foreach ($listsalesrepresentatives as $val) {
1898 $userstatic->id = $val['id'];
1899 $userstatic->lastname = $val['lastname'];
1900 $userstatic->firstname = $val['firstname'];
1901 $userstatic->email = $val['email'];
1902 $userstatic->status = $val['statut'];
1903 $userstatic->entity = $val['entity'];
1904 $userstatic->photo = $val['photo'];
1905 $userstatic->login = $val['login'];
1906 $userstatic->office_phone = $val['office_phone'];
1907 $userstatic->office_fax = $val['office_fax'];
1908 $userstatic->user_mobile = $val['user_mobile'];
1909 $userstatic->job = $val['job'];
1910 $userstatic->gender = $val['gender'];
1911 print ($nbofsalesrepresentative < 2) ? $userstatic->getNomUrl(-1, '', 0, 0, 12) : $userstatic->getNomUrl(-2);
1912 $j++;
1913 if ($j < $nbofsalesrepresentative) {
1914 print ' ';
1915 }
1916 }
1917 }
1918 //else print $langs->trans("NoSalesRepresentativeAffected");
1919 } else {
1920 print '&nbsp;';
1921 }
1922 print '</td>';
1923 if (!$i) {
1924 $totalarray['nbfield']++;
1925 }
1926 }
1927
1928 // Date start project
1929 if (!empty($arrayfields['p.dateo']['checked'])) {
1930 print '<td class="center">';
1931 print dol_print_date($db->jdate($obj->date_start), 'day');
1932 print '</td>';
1933 if (!$i) {
1934 $totalarray['nbfield']++;
1935 }
1936 }
1937 // Date end project
1938 if (!empty($arrayfields['p.datee']['checked'])) {
1939 print '<td class="center">';
1940 print dol_print_date($db->jdate($obj->date_end), 'day');
1941 print '</td>';
1942 if (!$i) {
1943 $totalarray['nbfield']++;
1944 }
1945 }
1946
1947 // Visibility
1948 if (!empty($arrayfields['p.public']['checked'])) {
1949 print '<td class="center">';
1950 if ($obj->public) {
1951 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1952 //print $langs->trans('SharedProject');
1953 } else {
1954 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1955 //print $langs->trans('PrivateProject');
1956 }
1957 print '</td>';
1958 if (!$i) {
1959 $totalarray['nbfield']++;
1960 }
1961 }
1962 // Assigned contacts of project
1963 if (!empty($arrayfields['c.assigned']['checked'])) {
1964 print '<td class="center nowraponall tdoverflowmax200">';
1965 print $stringassignedusers;
1966 print '</td>';
1967 if (!$i) {
1968 $totalarray['nbfield']++;
1969 }
1970 }
1971 // Opp Status
1972 if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
1973 $s = '';
1974 if ($obj->opp_status_code) {
1975 $s = $langs->trans("OppStatus".$obj->opp_status_code);
1976 if (empty($arrayfields['p.opp_percent']['checked']) && $obj->opp_percent) {
1977 $s .= ' ('.dol_escape_htmltag(price2num($obj->opp_percent, 1)).'%)';
1978 }
1979 }
1980 print '<td class="center tdoverflowmax150" title="'.$s.'">';
1981 print $s;
1982 print '</td>';
1983 if (!$i) {
1984 $totalarray['nbfield']++;
1985 }
1986 }
1987 // Opp Amount
1988 if (!empty($arrayfields['p.opp_amount']['checked'])) {
1989 print '<td class="right">';
1990 //if ($obj->opp_status_code)
1991 if (isset($obj->opp_amount) && strcmp($obj->opp_amount, '')) {
1992 print '<span class="amount">'.price($obj->opp_amount, 1, $langs, 1, -1, -1, '').'</span>';
1993 if (!isset($totalarray['val']['p.opp_amount'])) {
1994 $totalarray['val']['p.opp_amount'] = $obj->opp_amount;
1995 } else {
1996 $totalarray['val']['p.opp_amount'] += $obj->opp_amount;
1997 }
1998 }
1999 print '</td>';
2000 if (!$i) {
2001 $totalarray['nbfield']++;
2002 }
2003 if (!$i) {
2004 $totalarray['pos'][$totalarray['nbfield']] = 'p.opp_amount';
2005 }
2006 }
2007 // Opp percent
2008 if (!empty($arrayfields['p.opp_percent']['checked'])) {
2009 print '<td class="right">';
2010 if ($obj->opp_percent) {
2011 print price($obj->opp_percent, 1, $langs, 1, 0).'%';
2012 }
2013 print '</td>';
2014 if (!$i) {
2015 $totalarray['nbfield']++;
2016 }
2017 }
2018 // Opp weighted amount
2019 if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
2020 if (!isset($totalarray['val']['opp_weighted_amount'])) {
2021 $totalarray['val']['opp_weighted_amount'] = 0;
2022 }
2023 print '<td align="right">';
2024 if ($obj->opp_weighted_amount) {
2025 print '<span class="amount">'.price($obj->opp_weighted_amount, 1, $langs, 1, -1, -1, '').'</span>';
2026 $totalarray['val']['opp_weighted_amount'] += $obj->opp_weighted_amount;
2027 }
2028 print '</td>';
2029 if (!$i) {
2030 $totalarray['nbfield']++;
2031 $totalarray['pos'][$totalarray['nbfield']] = 'opp_weighted_amount';
2032 }
2033 }
2034 // Budget
2035 if (!empty($arrayfields['p.budget_amount']['checked'])) {
2036 print '<td class="right">';
2037 if ($obj->budget_amount != '') {
2038 print '<span class="amount">'.price($obj->budget_amount, 1, $langs, 1, -1, -1).'</span>';
2039 if (!isset($totalarray['val']['p.budget_amount'])) {
2040 $totalarray['val']['p.budget_amount'] = $obj->budget_amount;
2041 } else {
2042 $totalarray['val']['p.budget_amount'] += $obj->budget_amount;
2043 }
2044 }
2045 print '</td>';
2046 if (!$i) {
2047 $totalarray['nbfield']++;
2048 $totalarray['pos'][$totalarray['nbfield']] = 'p.budget_amount';
2049 }
2050 }
2051 // Usage opportunity
2052 if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
2053 print '<td class="">';
2054 if ($obj->usage_opportunity) {
2055 print yn($obj->usage_opportunity);
2056 }
2057 print '</td>';
2058 if (!$i) {
2059 $totalarray['nbfield']++;
2060 }
2061 }
2062 // Usage task
2063 if (!empty($arrayfields['p.usage_task']['checked'])) {
2064 print '<td class="">';
2065 if ($obj->usage_task) {
2066 print yn($obj->usage_task);
2067 }
2068 print '</td>';
2069 if (!$i) {
2070 $totalarray['nbfield']++;
2071 }
2072 }
2073 // Bill time
2074 if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
2075 print '<td class="">';
2076 if ($obj->usage_bill_time) {
2077 print yn($obj->usage_bill_time);
2078 }
2079 print '</td>';
2080 if (!$i) {
2081 $totalarray['nbfield']++;
2082 }
2083 }
2084 // Event Organization
2085 if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
2086 print '<td class="">';
2087 if ($obj->usage_organize_event) {
2088 print yn($obj->usage_organize_event);
2089 }
2090 print '</td>';
2091 if (!$i) {
2092 $totalarray['nbfield']++;
2093 }
2094 }
2095 // Allow unknown people to suggest conferences
2096 if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
2097 print '<td class="">';
2098 if ($obj->accept_conference_suggestions) {
2099 print yn($obj->accept_conference_suggestions);
2100 }
2101 print '</td>';
2102 if (!$i) {
2103 $totalarray['nbfield']++;
2104 }
2105 }
2106 // Allow unknown people to suggest booth
2107 if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
2108 print '<td class="">';
2109 if ($obj->accept_booth_suggestions) {
2110 print yn($obj->accept_booth_suggestions);
2111 }
2112 print '</td>';
2113 if (!$i) {
2114 $totalarray['nbfield']++;
2115 }
2116 }
2117 // Price of registration
2118 if (!empty($arrayfields['p.price_registration']['checked'])) {
2119 print '<td class="right">';
2120 if ($obj->price_registration != '') {
2121 print '<span class="amount">'.price($obj->price_registration, 1, $langs, 1, -1, -1).'</span>';
2122 $totalarray['val']['p.price_registration'] += $obj->price_registration;
2123 }
2124 print '</td>';
2125 if (!$i) {
2126 $totalarray['nbfield']++;
2127 }
2128 if (!$i) {
2129 $totalarray['pos'][$totalarray['nbfield']] = 'p.price_registration';
2130 }
2131 }
2132 // Price of booth
2133 if (!empty($arrayfields['p.price_booth']['checked'])) {
2134 print '<td class="right">';
2135 if ($obj->price_booth != '') {
2136 print '<span class="amount">'.price($obj->price_booth, 1, $langs, 1, -1, -1).'</span>';
2137 $totalarray['val']['p.price_booth'] += $obj->price_booth;
2138 }
2139 print '</td>';
2140 if (!$i) {
2141 $totalarray['nbfield']++;
2142 }
2143 if (!$i) {
2144 $totalarray['pos'][$totalarray['nbfield']] = 'p.price_booth';
2145 }
2146 }
2147 // Author
2148 if (!empty($arrayfields['u.login']['checked'])) {
2149 print '<td class="center tdoverflowmax150">';
2150 if ($userstatic->id) {
2151 print $userstatic->getNomUrl(-1);
2152 }
2153 print "</td>\n";
2154 if (!$i) {
2155 $totalarray['nbfield']++;
2156 }
2157 }
2158 // Extra fields
2159 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2160 // Fields from hook
2161 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
2162 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2163 print $hookmanager->resPrint;
2164 // Date creation
2165 if (!empty($arrayfields['p.datec']['checked'])) {
2166 print '<td class="center nowraponall">';
2167 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
2168 print '</td>';
2169 if (!$i) {
2170 $totalarray['nbfield']++;
2171 }
2172 }
2173 // Date modification
2174 if (!empty($arrayfields['p.tms']['checked'])) {
2175 print '<td class="center nowraponall">';
2176 print dol_print_date($db->jdate($obj->date_modification), 'dayhour', 'tzuser');
2177 print '</td>';
2178 if (!$i) {
2179 $totalarray['nbfield']++;
2180 }
2181 }
2182 // Email MsgID
2183 if (!empty($arrayfields['p.email_msgid']['checked'])) {
2184 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($obj->email_msgid).'">';
2185 print dol_escape_htmltag($obj->email_msgid);
2186 print '</td>';
2187 if (!$i) {
2188 $totalarray['nbfield']++;
2189 }
2190 }
2191 // Import key
2192 if (!empty($arrayfields['p.import_key']['checked'])) {
2193 print '<td class="right">'.dol_escape_htmltag($obj->import_key).'</td>';
2194 if (!$i) {
2195 $totalarray['nbfield']++;
2196 }
2197 }
2198 // Status
2199 if (!empty($arrayfields['p.fk_statut']['checked'])) {
2200 print '<td class="center">'.$object->getLibStatut(5).'</td>';
2201 if (!$i) {
2202 $totalarray['nbfield']++;
2203 }
2204 }
2205 // Action column
2206 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2207 print '<td class="nowrap center">';
2208 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2209 $selected = 0;
2210 if (in_array($object->id, $arrayofselected)) {
2211 $selected = 1;
2212 }
2213 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
2214 }
2215 print '</td>';
2216 if (!$i) {
2217 $totalarray['nbfield']++;
2218 }
2219 }
2220
2221 print '</tr>'."\n";
2222 }
2223
2224 $i++;
2225}
2226
2227// Show total line
2228include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
2229
2230// If no record found
2231if ($num == 0) {
2232 $colspan = 1;
2233 foreach ($arrayfields as $key => $val) {
2234 if (!empty($val['checked'])) {
2235 $colspan++;
2236 }
2237 }
2238 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
2239}
2240
2241$db->free($resql);
2242
2243$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
2244$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2245print $hookmanager->resPrint;
2246
2247print '</table>'."\n";
2248print '</div>'."\n";
2249
2250print '</form>'."\n";
2251
2252if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
2253 $hidegeneratedfilelistifempty = 1;
2254 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
2255 $hidegeneratedfilelistifempty = 0;
2256 }
2257
2258 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
2259 $formfile = new FormFile($db);
2260
2261 // Show list of available documents
2262 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
2263 $urlsource .= str_replace('&amp;', '&', $param);
2264
2265 $filedir = $diroutputmassaction;
2266 $genallowed = $permissiontoread;
2267 $delallowed = $permissiontoadd;
2268
2269 print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
2270}
2271
2272// End of page
2273llxFooter();
2274$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
$c
Definition line.php:327
Class to manage contact/addresses.
Class to manage standard extra fields.
Class to manage forms for categories.
Class to build HTML component for third parties management Only common components are here.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Class to manage Dolibarr users.
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0, $gm=false)
Generate a SQL string to make a filter into a range (for second of date until last second of date).
Definition date.lib.php:382
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
yn($yesno, $format=1, $color=0)
Return yes or no in current language.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.