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