dolibarr 25.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-2026 MDW <mdeweerd@users.noreply.github.com>
12 * Copyright (C) 2024-2026 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 * Copyright (C) 2025 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
37// Load Dolibarr environment
38require '../main.inc.php';
46require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
49require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
50require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
51require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
52if (isModEnabled('category')) {
53 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
54 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
55}
56
57// Load translation files required by the page
58$langs->loadLangs(array('projects', 'companies', 'commercial'));
59if (isModEnabled('eventorganization') && $conf->eventorganization->enabled) {
60 $langs->loadLangs(array('eventorganization'));
61}
62
63$action = GETPOST('action', 'aZ09');
64$massaction = GETPOST('massaction', 'alpha');
65$show_files = GETPOSTINT('show_files');
66$confirm = GETPOST('confirm', 'alpha');
67$toselect = GETPOST('toselect', 'array:int');
68$optioncss = GETPOST('optioncss', 'alpha');
69$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'projectlist';
70$mode = GETPOST('mode', 'alpha');
71$groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut'. Must be a field into $object->fields
72
73$title = $langs->trans("Projects");
74
75
76$diroutputmassaction = $conf->project->dir_output.'/temp/massgeneration/'.$user->id;
77
78$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
79$sortfield = GETPOST('sortfield', 'aZ09comma');
80$sortorder = GETPOST('sortorder', 'aZ09comma');
81$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
82if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
83 // If $page is not defined, or '' or -1 or if we click on clear filters
84 $page = 0;
85}
86if (!$sortfield) {
87 $sortfield = "p.ref";
88}
89if (!$sortorder) {
90 $sortorder = "ASC";
91}
92$offset = $limit * $page;
93$pageprev = $page - 1;
94$pagenext = $page + 1;
95
96$search_all = GETPOST('search_all', 'alphanohtml');
97$search_entity = GETPOSTINT('search_entity');
98$search_id = GETPOST("search_id", 'alpha');
99$search_ref = GETPOST("search_ref", 'alpha');
100$search_label = GETPOST("search_label", 'alpha');
101$search_note_public = GETPOST('search_note_public', 'alphanohtml');
102$search_note_private = GETPOST('search_note_private', 'alphanohtml');
103$search_societe = GETPOST("search_societe", 'alpha');
104$search_societe_alias = GETPOST("search_societe_alias", 'alpha');
105$search_societe_country = GETPOST("search_societe_country", 'alpha');
106$search_societe_ref_customer = GETPOST("search_societe_ref_customer", 'alpha');
107$search_societe_ref_supplier = GETPOST("search_societe_ref_supplier", 'alpha');
108$search_opp_status = GETPOST("search_opp_status", 'alpha');
109$search_opp_percent = GETPOST("search_opp_percent", 'alpha');
110$search_opp_amount = GETPOST("search_opp_amount", 'alpha');
111$search_budget_amount = GETPOST("search_budget_amount", 'alpha');
112$search_parent_ref = GETPOST('search_parent_ref', 'alpha');
113$search_parent_label = GETPOST('search_parent_label', 'alpha');
114$search_public = GETPOST("search_public", 'intcomma');
115$search_project_user = GETPOSTINT('search_project_user');
116$search_project_contact = GETPOSTINT('search_project_contact');
117$search_sale = GETPOSTINT('search_sale');
118$search_usage_opportunity = GETPOST('search_usage_opportunity', 'intcomma');
119$search_usage_task = GETPOST('search_usage_task', 'intcomma');
120$search_usage_bill_time = GETPOST('search_usage_bill_time', 'intcomma');
121$search_usage_event_organization = GETPOST('search_usage_event_organization', 'intcomma');
122$search_accept_conference_suggestions = GETPOST('search_accept_conference_suggestions', 'intcomma');
123$search_accept_booth_suggestions = GETPOST('search_accept_booth_suggestions', 'intcomma');
124$search_price_registration = GETPOST("search_price_registration", 'alpha');
125$search_price_booth = GETPOST("search_price_booth", 'alpha');
126$search_login = GETPOST('search_login', 'alpha');
127$search_import_key = GETPOST('search_import_key', 'alpha');
128
129$searchCategoryUserOperator = 0;
130if (GETPOSTISSET('formfilteraction')) {
131 $searchCategoryUserOperator = GETPOSTINT('search_category_user_operator');
132} elseif (getDolGlobalString('MAIN_SEARCH_CAT_USER_OR_BY_DEFAULT')) {
133 $searchCategoryUserOperator = getDolGlobalString('MAIN_SEARCH_CAT_USER_OR_BY_DEFAULT');
134}
135
136$searchCategoryProjectOperator = 0;
137if (GETPOSTISSET('formfilteraction')) {
138 $searchCategoryProjectOperator = GETPOSTINT('search_category_project_operator');
139} elseif (getDolGlobalString('MAIN_SEARCH_CAT_PROJECT_OR_BY_DEFAULT')) {
140 $searchCategoryProjectOperator = getDolGlobalString('MAIN_SEARCH_CAT_PROJECT_OR_BY_DEFAULT');
141}
142
143/*
144$searchCategoryCustomerOperator = 0;
145if (GETPOSTISSET('formfilteraction')) {
146 $searchCategoryCustomerOperator = GETPOSTINT('search_category_customer_operator');
147} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
148 $searchCategoryCustomerOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
149}
150$searchCategoryCustomerList = GETPOST('search_category_customer_list', 'array:int');
151*/
152
153$search_omitChildren = 0;
154if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
155 $search_omitChildren = GETPOST('search_omitChildren', 'alpha') == 'on' ? 1 : 0;
156}
157
158// Default to no permissions
159$permissiontoread = 0;
160$permissiontoadd = 0;
161
162
163$mine = ((GETPOST('mode') == 'mine') ? 1 : 0);
164if ($mine) {
165 $search_project_user = $user->id;
166 $mine = 0;
167}
168
169$search_sday = GETPOSTINT('search_sday');
170$search_smonth = GETPOSTINT('search_smonth');
171$search_syear = GETPOSTINT('search_syear');
172$search_eday = GETPOSTINT('search_eday');
173$search_emonth = GETPOSTINT('search_emonth');
174$search_eyear = GETPOSTINT('search_eyear');
175
176$search_date_start_startmonth = GETPOSTINT('search_date_start_startmonth');
177$search_date_start_startyear = GETPOSTINT('search_date_start_startyear');
178$search_date_start_startday = GETPOSTINT('search_date_start_startday');
179$search_date_start_start = GETPOSTDATE('search_date_start_start'); // Use tzserver
180$search_date_start_endmonth = GETPOSTINT('search_date_start_endmonth');
181$search_date_start_endyear = GETPOSTINT('search_date_start_endyear');
182$search_date_start_endday = GETPOSTINT('search_date_start_endday');
183$search_date_start_end = GETPOSTDATE('search_date_start_end', 'end'); // Use tzserver
184
185$search_date_end_startmonth = GETPOSTINT('search_date_end_startmonth');
186$search_date_end_startyear = GETPOSTINT('search_date_end_startyear');
187$search_date_end_startday = GETPOSTINT('search_date_end_startday');
188$search_date_end_start = GETPOSTDATE('search_date_end_start'); // Use tzserver
189$search_date_end_endmonth = GETPOSTINT('search_date_end_endmonth');
190$search_date_end_endyear = GETPOSTINT('search_date_end_endyear');
191$search_date_end_endday = GETPOSTINT('search_date_end_endday');
192$search_date_end_end = GETPOSTDATE('search_date_end_end', 'end');
193; // Use tzserver
194
195$search_date_creation_startmonth = GETPOSTINT('search_date_creation_startmonth');
196$search_date_creation_startyear = GETPOSTINT('search_date_creation_startyear');
197$search_date_creation_startday = GETPOSTINT('search_date_creation_startday');
198$search_date_creation_start = GETPOSTDATE('search_date_creation_start'); // Use tzserver
199$search_date_creation_endmonth = GETPOSTINT('search_date_creation_endmonth');
200$search_date_creation_endyear = GETPOSTINT('search_date_creation_endyear');
201$search_date_creation_endday = GETPOSTINT('search_date_creation_endday');
202$search_date_creation_end = GETPOSTDATE('search_date_creation_end', 'end'); // Use tzserver
203
204$search_date_modif_startmonth = GETPOSTINT('search_date_modif_startmonth');
205$search_date_modif_startyear = GETPOSTINT('search_date_modif_startyear');
206$search_date_modif_startday = GETPOSTINT('search_date_modif_startday');
207$search_date_modif_start = GETPOSTDATE('search_date_modif_start'); // Use tzserver
208$search_date_modif_endmonth = GETPOSTINT('search_date_modif_endmonth');
209$search_date_modif_endyear = GETPOSTINT('search_date_modif_endyear');
210$search_date_modif_endday = GETPOSTINT('search_date_modif_endday');
211$search_date_modif_end = GETPOSTDATE('search_date_modif_end', 'end'); // Use tzserver
212
213$search_category_array = array();
214$search_category_user_array = array();
215
216if (isModEnabled('category')) {
217 $search_category_array = GETPOST("search_category_".Categorie::TYPE_PROJECT."_list", "array");
218 $search_category_user_array = GETPOST("search_category_".Categorie::TYPE_USER."_list", "array");
219}
220
221if (GETPOSTISARRAY('search_status') || GETPOST('search_status_multiselect')) {
222 $search_status = implode(',', GETPOST('search_status', 'array:intcomma'));
223} else {
224 $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : (GETPOSTISSET('search_all') ? '' : '0,1'));
225}
226
227$search_option = GETPOST('search_option', 'alpha');
228if ($search_option == 'late') {
229 $search_status = '1';
230}
231// Initialize technical objects
232$object = new Project($db);
233$hookmanager->initHooks(array('projectlist'));
234$extrafields = new ExtraFields($db);
235
236// Fetch optionals attributes and labels
237$extrafields->fetch_name_optionals_label($object->table_element);
238
239$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
240
241$fieldstosearchall = array();
242// List of fields to search into when doing a "search in all"
243foreach ($object->fields as $key => $val) {
244 if (empty($val['searchall'])) {
245 continue;
246 }
247
248 // Don't allow search in private notes for external users when doing "search in all"
249 if (!empty($user->socid) && $key == "note_private") {
250 continue;
251 }
252
253 $fieldstosearchall['p.'.$key] = $val['label'];
254}
255
256// Add name object fields to "search in all"
257$fieldstosearchall['s.nom'] = "ThirdPartyName";
258$fieldstosearchall['s.name_alias'] = "AliasNameShort";
259$fieldstosearchall['s.code_client'] = "CustomerCode";
260
261// Definition of array of fields for columns
262$tableprefix = 'p';
263$arrayfields = array();
264foreach ($object->fields as $key => $val) {
265 // If $val['visible']==0, then we never show the field
266 if (!empty($val['visible'])) {
267 $visible = (int) dol_eval((string) $val['visible'], 1);
268 $arrayfields[$tableprefix.'.'.$key] = array(
269 'label' => $val['label'],
270 'checked' => (($visible < 0) ? '0' : '1'),
271 'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
272 'position' => $val['position'],
273 'help' => isset($val['help']) ? $val['help'] : ''
274 );
275 }
276}
277// Extra fields
278include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
279
280// Add non object fields to fields for list
281$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => '1', 'position' => 21, 'enabled' => (!isModEnabled('societe') ? '0' : '1'));
282$arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => '0', 'position' => 22);
283$arrayfields['s.code_client'] = array('label' => "RefCustomer", 'checked' => '0', 'position' => 23);
284$arrayfields['s.code_fournisseur'] = array('label' => "RefSupplier", 'checked' => '0', 'position' => 24);
285$arrayfields['co.country_code'] = array('label' => "Country", 'checked' => '-1', 'position' => 25);
286$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => '0', 'position' => 26);
287$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => '1', 'position' => 120);
288$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => '0', 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? '0' : '1'), 'position' => 106);
289$arrayfields['u.login'] = array('label' => "Author", 'checked' => '-1', 'position' => 165);
290$arrayfields['p.note_public'] = array('label' => 'NotePublic', 'checked' => '0', 'position' => 170, 'enabled' => (string) (int) (!getDolGlobalString('MAIN_LIST_HIDE_PUBLIC_NOTES')));
291$arrayfields['p.note_private'] = array('label' => 'NotePrivate', 'checked' => '0', 'position' => 171, 'enabled' => (string) (int) (!getDolGlobalString('MAIN_LIST_HIDE_PRIVATE_NOTES')));
292// Force some fields according to search_usage filter...
293//if (GETPOST('search_usage_opportunity')) {
294//$arrayfields['p.usage_opportunity']['visible'] = 1; // Not required, filter on search_opp_status is enough
295//$arrayfields['p.usage_opportunity']['checked'] = 1; // Not required, filter on search_opp_status is enough
296//}
297if (GETPOST('search_usage_event_organization')) {
298 if (array_key_exists('p.fk_opp_status', $arrayfields)) {
299 $arrayfields['p.fk_opp_status']['enabled'] = '0';
300 }
301 if (array_key_exists('p.fk_opp_amount', $arrayfields)) {
302 $arrayfields['p.opp_amount']['enabled'] = '0';
303 }
304 if (array_key_exists('p.fk_opp_percent', $arrayfields)) {
305 $arrayfields['p.opp_percent']['enabled'] = '0';
306 }
307 $arrayfields['opp_weighted_amount']['enabled'] = '0';
308 if (array_key_exists('p.usage_organize_event', $arrayfields)) {
309 $arrayfields['p.usage_organize_event']['visible'] = '1';
310 $arrayfields['p.usage_organize_event']['checked'] = '1';
311 }
312}
313
314// Force this field to be visible
315if ($contextpage == 'lead') {
316 if (array_key_exists('p.fk_opp_status', $arrayfields)) {
317 $arrayfields['p.fk_opp_status']['enabled'] = '1';
318 $arrayfields['p.fk_opp_status']['visible'] = '1';
319 }
320}
321
322// Add hook to complete $arrayfields
323$parameters = array('arrayfields' => &$arrayfields);
324$reshook = $hookmanager->executeHooks('completeArrayFields', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
325
326$object->fields = dol_sort_array($object->fields, 'position');
327$arrayfields = dol_sort_array($arrayfields, 'position');
328
329// Set $groupbyvalues with array of all possible dictionary values (even if no data for this value exists).
330// TODO Move this into a inc file
331$groupbyvalues = array();
332$groupofcollpasedvalues = array();
333$groupbyold = null;
334if ($mode == 'kanbangroupby' && $groupby) {
335 $groupbyfield = preg_replace('/[a-z]+\./', '', $groupby);
336 if (!empty($object->fields[$groupbyfield]['alias'])) {
337 $groupbyfield = $object->fields[$groupbyfield]['alias'];
338 }
339 if (!in_array(preg_replace('/[a-z]+\./', '', $groupby), array_keys($object->fields))) {
340 $groupby = '';
341 } else {
342 if (!empty($object->fields[$groupby]['arrayofkeyval'])) {
343 $groupbyvalues = $object->fields[$groupby]['arrayofkeyval'];
344 } elseif (!empty($object->fields[preg_replace('/[a-z]\./', '', $groupby)]['arrayofkeyval'])) {
345 $groupbyvalues = $object->fields[preg_replace('/[a-z]\./', '', $groupby)]['arrayofkeyval'];
346 } else {
347 // var_dump($object->fields[$groupby]['type']);
348 // If type is 'integer:Object:classpath', for example "integer:CLeadStatus:core/class/cleadstatus.class.php"
349 // TODO
350 // $groupbyvalues = ...
351
352 $sql = "SELECT cls.rowid, cls.code, cls.percent, cls.label, cls.position";
353 $sql .= " FROM ".MAIN_DB_PREFIX."c_lead_status as cls";
354 $sql .= " WHERE active = 1";
355 //$sql .= " AND cls.code <> 'LOST'";
356 //$sql .= " AND cls.code <> 'WON'";
357 $sql .= $db->order('cls.position,cls.rowid', 'ASC'); // Must use the same order key than the key in $groupby
358 $resql = $db->query($sql);
359 if ($resql) {
360 $num = $db->num_rows($resql);
361
362 $i = 1;
363 while ($i < ($num + 1)) { // $num + 1 because we added the undefined entry so we start with $i=1;
364 $objp = $db->fetch_object($resql);
365 $groupbyvalues[$i] = array('id' => (string) $objp->rowid, 'label' => $objp->label);
366 // If this is a group code that need to be collapsed
367 if ($objp->code == 'WON') {
368 $groupofcollpasedvalues[$i] = array('id' => (string) $objp->rowid, 'label' => $objp->label);
369 } elseif ($objp->code == 'LOST') {
370 $groupofcollpasedvalues[$i] = array('id' => (string) $objp->rowid, 'label' => $objp->label);
371 }
372
373 $i++;
374 }
375 }
376 }
377 /*var_dump($groupbyvalues);
378 var_dump($groupofcollpasedvalues);
379 */
380 }
381
382 // Add a filter on the group by if not yet included first
383 $groupbystringforsql = $groupby;
384 // Special case
385 if ($groupby == 'p.fk_opp_status') {
386 $groupbystringforsql = 'cls.position,p.fk_opp_status';
387 }
388
389 if ($groupbystringforsql && !preg_match('/^'.preg_quote($db->sanitize($groupbystringforsql), '/').'/', $sortfield)) {
390 $sortfield = $db->sanitize($groupbystringforsql).($sortfield ? ",".$sortfield : "");
391 $sortorder = "ASC".($sortfield ? ",".$sortorder : "");
392 }
393}
394
395// Security check
396$socid = GETPOSTINT('socid');
397//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.
398if ($socid > 0) {
399 $soc = new Societe($db);
400 $soc->fetch($socid);
401 $title .= ' (<a href="list.php">'.$soc->name.'</a>)';
402}
403
404if (!$user->hasRight('project', 'read')) {
406}
407
408
409/*
410 * Actions
411 */
412
413$error = 0;
414if (GETPOST('cancel', 'alpha')) {
415 $action = 'list';
416 $massaction = '';
417}
418if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
419 $massaction = '';
420}
421
422$parameters = array('socid' => $socid, 'arrayfields' => &$arrayfields);
423$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
424if ($reshook < 0) {
425 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
426}
427
428if (empty($reshook)) {
429 // Selection of new fields
430 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
431
432 // Purge search criteria
433 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
434 $search_all = '';
435 $search_id = "";
436 $search_ref = "";
437 $search_label = "";
438 $search_note_public = '';
439 $search_note_private = '';
440 $search_societe = "";
441 $search_societe_ref_customer = "";
442 $search_societe_ref_supplier = "";
443 $search_societe_alias = '';
444 $search_societe_country = '';
445 $search_status = -1;
446 $search_option = '';
447 $search_opp_status = -1;
448 $search_opp_amount = '';
449 $search_opp_percent = '';
450 $search_budget_amount = '';
451 $search_parent_ref = '';
452 $search_parent_label = '';
453 $search_public = "";
454 $search_sale = "";
455 $search_project_user = '';
456 $search_project_contact = '';
457 $search_sday = "";
458 $search_smonth = "";
459 $search_syear = "";
460 $search_eday = "";
461 $search_emonth = "";
462 $search_eyear = "";
463 $search_date_start_startmonth = "";
464 $search_date_start_startyear = "";
465 $search_date_start_startday = "";
466 $search_date_start_start = "";
467 $search_date_start_endmonth = "";
468 $search_date_start_endyear = "";
469 $search_date_start_endday = "";
470 $search_date_start_end = "";
471 $search_date_end_startmonth = "";
472 $search_date_end_startyear = "";
473 $search_date_end_startday = "";
474 $search_date_end_start = "";
475 $search_date_end_endmonth = "";
476 $search_date_end_endyear = "";
477 $search_date_end_endday = "";
478 $search_date_end_end = "";
479 $search_date_creation_startmonth = "";
480 $search_date_creation_startyear = "";
481 $search_date_creation_startday = "";
482 $search_date_creation_start = "";
483 $search_date_creation_endmonth = "";
484 $search_date_creation_endyear = "";
485 $search_date_creation_endday = "";
486 $search_date_creation_end = "";
487 $search_date_modif_startmonth = "";
488 $search_date_modif_startyear = "";
489 $search_date_modif_startday = "";
490 $search_date_modif_start = "";
491 $search_date_modif_endmonth = "";
492 $search_date_modif_endyear = "";
493 $search_date_modif_endday = "";
494 $search_date_modif_end = "";
495 $search_usage_opportunity = '';
496 $search_usage_task = '';
497 $search_usage_bill_time = '';
498 $search_usage_event_organization = '';
499 $search_accept_conference_suggestions = '';
500 $search_accept_booth_suggestions = '';
501 $search_price_registration = '';
502 $search_price_booth = '';
503 $search_login = '';
504 $search_import_key = '';
505 $search_entity = '';
506 $toselect = array();
507 $search_array_options = array();
508 $search_category_array = array();
509 $search_category_user_array = array();
510 }
511
512
513 // Mass actions
514 $objectclass = 'Project';
515 $objectlabel = 'Project';
516 $permissiontoread = $user->hasRight('projet', 'lire');
517 $permissiontodelete = $user->hasRight('projet', 'supprimer');
518 $permissiontoadd = $user->hasRight('projet', 'creer');
519 $uploaddir = $conf->project->dir_output;
520
521 global $error;
522 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
523
524 // Close records
525 if (!$error && $massaction == 'close' && $user->hasRight('projet', 'creer')) {
526 $db->begin();
527
528 $objecttmp = new $objectclass($db);
529 $nbok = 0;
530 foreach ($toselect as $toselectid) {
531 $result = $objecttmp->fetch($toselectid);
532 if ($result > 0) {
533 $userWrite = $object->restrictedProjectArea($user, 'write');
534 if ($userWrite > 0 && $objecttmp->statut == 1) {
535 $result = $objecttmp->setClose($user);
536 if ($result <= 0) {
537 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
538 $error++;
539 break;
540 } else {
541 $nbok++;
542 }
543 } elseif ($userWrite <= 0) {
544 setEventMessages($langs->trans("DontHavePermissionForCloseProject", $objecttmp->ref), null, 'warnings');
545 } else {
546 setEventMessages($langs->trans("DontHaveTheValidateStatus", $objecttmp->ref), null, 'warnings');
547 }
548 } else {
549 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
550 $error++;
551 break;
552 }
553 }
554
555 if (!$error) {
556 setEventMessages($langs->trans("RecordsClosed", $nbok), null, 'mesgs');
557 $db->commit();
558 } else {
559 $db->rollback();
560 }
561 }
562}
563
564
565/*
566 * View
567 */
568
569unset($_SESSION['pageforbacktolist']['project']);
570
571$form = new Form($db);
572$formcompany = new FormCompany($db);
573$companystatic = new Societe($db);
574$taskstatic = new Task($db);
575$formother = new FormOther($db);
576$formproject = new FormProjets($db);
577$userstatic = new User($db);
578
579$now = dol_now();
580
581$help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
582$title = $langs->trans("LeadsOrProjects");
583if (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
584 $title = $langs->trans("Projects");
585}
586if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
587 $title = $langs->trans("Leads");
588}
589$morejs = array();
590$morecss = array();
591
592
593// Get list of project id allowed to user (in a string list separated by comma)
594$projectsListId = '';
595if (!$user->hasRight('projet', 'all', 'lire')) {
596 $projectsListId = $object->getProjectsAuthorizedForUser($user, 0, 1, $socid);
597}
598
599// Get id of types of contacts for projects (This list never contains a lot of elements)
600$listofprojectcontacttype = array();
601$listofprojectcontacttypeexternal = array();
602$sql = "SELECT ctc.rowid, ctc.code, ctc.source FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
603$sql .= " WHERE ctc.element = '".$db->escape($object->element)."'";
604$resql = $db->query($sql);
605if ($resql) {
606 while ($obj = $db->fetch_object($resql)) {
607 if ($obj->source == 'internal') {
608 $listofprojectcontacttype[$obj->rowid] = $obj->code;
609 } else {
610 $listofprojectcontacttypeexternal[$obj->rowid] = $obj->code;
611 }
612 }
613} else {
614 dol_print_error($db);
615}
616if (count($listofprojectcontacttype) == 0) {
617 $listofprojectcontacttype[0] = '0'; // To avoid sql syntax error if not found
618}
619if (count($listofprojectcontacttypeexternal) == 0) {
620 $listofprojectcontacttypeexternal[0] = '0'; // To avoid sql syntax error if not found
621}
622
623$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
624$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
625
626// Build and execute select
627// --------------------------------------------------------------------
628$sql = "SELECT";
629$sql .= " p.rowid as id, p.ref, p.title, p.fk_statut as status, cls.position, p.fk_project, ";
630$sql .= $db->ifsql("p.fk_opp_status IS NULL", "0", "p.fk_opp_status")." as fk_opp_status, p.public, p.fk_user_creat,";
631$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,";
632$sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,";
633$sql .= " p.email_msgid, p.import_key,";
634$sql .= " p.accept_conference_suggestions, p.accept_booth_suggestions, p.price_registration, p.price_booth,";
635$sql .= " p.note_public, p.note_private,";
636$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, s.code_fournisseur,";
637$sql .= " country.code as country_code,";
638$sql .= " cls.code as opp_status_code,";
639$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';
640// Add fields from extrafields
641if (!empty($extrafields->attributes[$object->table_element]['label'])) {
642 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
643 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
644 }
645}
646// Add fields from hooks
647$parameters = array();
648$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
649$sql .= $hookmanager->resPrint;
650$sql = preg_replace('/,\s*$/', '', $sql);
651
652$sqlfields = $sql; // $sql fields to remove for count total
653
654$sql .= " FROM ".$db->prefix().$object->table_element." as p";
655if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
656 $sql .= " LEFT JOIN ".$db->prefix().$object->table_element."_extrafields as ef on (p.rowid = ef.fk_object)";
657}
658$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
659$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on country.rowid = s.fk_pays";
660$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls on p.fk_opp_status = cls.rowid";
661$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user AS u ON p.fk_user_creat = u.rowid';
662$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.$object->table_element.' AS pa ON p.fk_project = pa.rowid';
663// We'll need this table joined to the select in order to filter by sale
664// No check is done on company permission because readability is managed by public status of project and assignment.
665//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";
666// Add table from hooks
667$parameters = array();
668$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
669$sql .= $hookmanager->resPrint;
670if ($search_entity > 0) {
671 $sql .= " WHERE p.entity = ".((int) $search_entity);
672} else {
673 $sql .= " WHERE p.entity IN (".getEntity('project').')';
674}
675if (!$user->hasRight('projet', 'all', 'lire')) {
676 $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; // public and assigned to, or restricted to company for external users
677}
678// No need to check if company is external user, as filtering of projects must be done by getProjectsAuthorizedForUser
679if ($socid > 0) {
680 $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)
681}
682if ($search_id) {
683 $sql .= natural_search('p.rowid', $search_id, 1);
684}
685if ($search_ref) {
686 $sql .= natural_search('p.ref', $search_ref);
687}
688if ($search_label) {
689 $sql .= natural_search('p.title', $search_label);
690}
691if ($search_note_public != '') {
692 $sql .= natural_search('p.note_public', $search_note_public);
693}
694if ($search_note_private != '') {
695 $sql .= natural_search('p.note_private', $search_note_private);
696}
697if ($search_parent_ref) {
698 $sql .= natural_search('pa.ref', $search_parent_ref);
699}
700if ($search_parent_label) {
701 $sql .= natural_search('pa.title', $search_parent_label);
702}
703if (empty($arrayfields['s.name_alias']['checked']) && $search_societe) {
704 $sql .= natural_search(array("s.nom", "s.name_alias"), $search_societe);
705} else {
706 if ($search_societe) {
707 $sql .= natural_search('s.nom', $search_societe);
708 }
709 if ($search_societe_alias) {
710 $sql .= natural_search('s.name_alias', $search_societe_alias);
711 }
712}
713if ($search_societe_ref_customer) {
714 $sql .= natural_search('s.code_client', $search_societe_ref_customer);
715}
716if ($search_societe_ref_supplier) {
717 $sql .= natural_search('s.code_fournisseur', $search_societe_ref_supplier);
718}
719if ($search_societe_country) {
720 $sql .= natural_search('country.code', $search_societe_country);
721}
722if ($search_opp_amount) {
723 $sql .= natural_search('p.opp_amount', $search_opp_amount, 1);
724}
725if ($search_opp_percent) {
726 $sql .= natural_search('p.opp_percent', $search_opp_percent, 1);
727}
728$sql .= dolSqlDateFilter('p.dateo', $search_sday, $search_smonth, $search_syear);
729$sql .= dolSqlDateFilter('p.datee', $search_eday, $search_emonth, $search_eyear);
730
731if ($search_date_start_start) {
732 $sql .= " AND p.dateo >= '".$db->idate($search_date_start_start)."'";
733}
734if ($search_date_start_end) {
735 $sql .= " AND p.dateo <= '".$db->idate($search_date_start_end)."'";
736}
737
738if ($search_date_end_start) {
739 $sql .= " AND p.datee >= '".$db->idate($search_date_end_start)."'";
740}
741if ($search_date_end_end) {
742 $sql .= " AND p.datee <= '".$db->idate($search_date_end_end)."'";
743}
744
745if ($search_date_creation_start) {
746 $sql .= " AND p.datec >= '".$db->idate($search_date_creation_start)."'";
747}
748if ($search_date_creation_end) {
749 $sql .= " AND p.datec <= '".$db->idate($search_date_creation_end)."'";
750}
751
752if ($search_date_modif_start) {
753 $sql .= " AND p.tms >= '".$db->idate($search_date_modif_start)."'";
754}
755if ($search_date_modif_end) {
756 $sql .= " AND p.tms <= '".$db->idate($search_date_modif_end)."'";
757}
758
759if ($search_all) {
760 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
761}
762if ($search_status != '' && $search_status != '-1') {
763 if ($search_status == 99) {
764 $sql .= " AND p.fk_statut IN (0,1)";
765 } else {
766 $sql .= " AND p.fk_statut IN (".$db->sanitize($db->escape($search_status)).")";
767 }
768}
769if ($search_option == 'late') {
770 $sql .= " AND p.datee < '".$db->idate(dol_now() - $conf->project->warning_delay)."'";
771}
772if ($search_opp_status) {
773 if (is_numeric($search_opp_status) && $search_opp_status > 0) {
774 $sql .= " AND p.fk_opp_status = ".((int) $search_opp_status);
775 }
776 if ($search_opp_status == 'all') {
777 $sql .= " AND (p.fk_opp_status IS NOT NULL AND p.fk_opp_status <> -1)";
778 }
779 if ($search_opp_status == 'openedopp') {
780 $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'))";
781 }
782 if ($search_opp_status == 'notopenedopp') {
783 $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'))";
784 }
785 if ($search_opp_status == 'none') {
786 $sql .= " AND (p.fk_opp_status IS NULL OR p.fk_opp_status = -1)";
787 }
788}
789if ($search_public != '') {
790 $sql .= " AND p.public = ".((int) $search_public);
791}
792// No check is done on company permission because readability is managed by public status of project and assignment.
793//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))";
794// Search on sale representative
795if ($search_sale && $search_sale != '-1') {
796 if ($search_sale == -2) {
797 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".$db->prefix()."societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
798 } elseif ($search_sale > 0) {
799 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".$db->prefix()."societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
800 }
801}
802if ($search_project_user > 0) {
803 $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).")";
804}
805if ($search_project_contact > 0) {
806 $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).")";
807}
808if ($search_opp_amount != '') {
809 $sql .= natural_search('p.opp_amount', $search_opp_amount, 1);
810}
811if ($search_budget_amount != '') {
812 $sql .= natural_search('p.budget_amount', $search_budget_amount, 1);
813}
814if ($search_usage_opportunity != '' && $search_usage_opportunity >= 0) {
815 $sql .= natural_search('p.usage_opportunity', $search_usage_opportunity, 2);
816}
817if ($search_usage_task != '' && $search_usage_task >= 0) {
818 $sql .= natural_search('p.usage_task', $search_usage_task, 2);
819}
820if ($search_usage_bill_time != '' && $search_usage_bill_time >= 0) {
821 $sql .= natural_search('p.usage_bill_time', $search_usage_bill_time, 2);
822}
823if ($search_usage_event_organization != '' && $search_usage_event_organization >= 0) {
824 $sql .= natural_search('p.usage_organize_event', $search_usage_event_organization, 2);
825}
826if ($search_accept_conference_suggestions != '' && $search_accept_conference_suggestions >= 0) {
827 $sql .= natural_search('p.accept_conference_suggestions', $search_accept_conference_suggestions, 2);
828}
829if ($search_accept_booth_suggestions != '' && $search_accept_booth_suggestions >= 0) {
830 $sql .= natural_search('p.accept_booth_suggestions', $search_accept_booth_suggestions, 2);
831}
832if ($search_price_registration != '') {
833 $sql .= natural_search('p.price_registration', $search_price_registration, 1);
834}
835if ($search_price_booth != '') {
836 $sql .= natural_search('p.price_booth', $search_price_booth, 1);
837}
838if ($search_login) {
839 $sql .= natural_search(array('u.login', 'u.firstname', 'u.lastname'), $search_login);
840}
841if ($search_import_key) {
842 $sql .= natural_search(array('p.import_key'), $search_import_key);
843}
844if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
845 if ($search_omitChildren == 1) {
846 $sql .= " AND p.fk_project IS NULL";
847 }
848}
849
850// Search for tag/category of User ($searchCategoryUserList is an array of ID)
851$searchCategoryUserList = $search_category_user_array;
852if (!empty($searchCategoryUserList)) {
853 $searchCategoryUserSqlList = array();
854 $listofcategoryid = '';
855 foreach ($searchCategoryUserList as $searchCategoryUser) {
856 if (intval($searchCategoryUser) == -2) {
857 $searchCategoryUserSqlList[] = "NOT EXISTS (SELECT ck.fk_user FROM ".MAIN_DB_PREFIX."categorie_user as ck WHERE u.rowid = ck.fk_user)";
858 } elseif (intval($searchCategoryUser) > 0) {
859 if ($searchCategoryUserOperator == 0) {
860 $searchCategoryUserSqlList[] = " EXISTS (SELECT ck.fk_user FROM ".MAIN_DB_PREFIX."categorie_user as ck WHERE u.rowid = ck.fk_user AND ck.fk_categorie = ".((int) $searchCategoryUser).")";
861 } else {
862 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryUser);
863 }
864 }
865 }
866 if ($listofcategoryid) {
867 $searchCategoryUserSqlList[] = " EXISTS (SELECT ck.fk_user FROM ".MAIN_DB_PREFIX."categorie_user as ck WHERE u.rowid = ck.fk_User AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
868 }
869 if ($searchCategoryUserOperator == 1) {
870 if (!empty($searchCategoryUserSqlList)) {
871 $sql .= " AND (".implode(' OR ', $searchCategoryUserSqlList).")";
872 }
873 } else {
874 if (!empty($searchCategoryUserSqlList)) {
875 $sql .= " AND (".implode(' AND ', $searchCategoryUserSqlList).")";
876 }
877 }
878}
879
880// Search for tag/category or Project ($searchCategoryProjectList is an array of ID)
881$searchCategoryProjectList = $search_category_array;
882if (!empty($searchCategoryProjectList)) {
883 $searchCategoryProjectSqlList = array();
884 $listofcategoryid = '';
885 foreach ($searchCategoryProjectList as $searchCategoryProject) {
886 if (intval($searchCategoryProject) == -2) {
887 $searchCategoryProjectSqlList[] = "NOT EXISTS (SELECT ck.fk_project FROM ".MAIN_DB_PREFIX."categorie_project as ck WHERE p.rowid = ck.fk_project)";
888 } elseif (intval($searchCategoryProject) > 0) {
889 if ($searchCategoryProjectOperator == 0) {
890 $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).")";
891 } else {
892 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryProject);
893 }
894 }
895 }
896 if ($listofcategoryid) {
897 $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)."))";
898 }
899 if ($searchCategoryProjectOperator == 1) {
900 if (!empty($searchCategoryProjectSqlList)) {
901 $sql .= " AND (".implode(' OR ', $searchCategoryProjectSqlList).")";
902 }
903 } else {
904 if (!empty($searchCategoryProjectSqlList)) {
905 $sql .= " AND (".implode(' AND ', $searchCategoryProjectSqlList).")";
906 }
907 }
908}
909
910// Search for tag/category of Customer Third party ($searchCategoryCustomerList is an array of ID)
911/*
912$searchCategoryCustomerSqlList = array();
913if ($searchCategoryCustomerOperator == 1) {
914 $existsCategoryCustomerList = array();
915 foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
916 if (intval($searchCategoryCustomer) == -2) {
917 $sqlCategoryCustomerNotExists = " NOT EXISTS (";
918 $sqlCategoryCustomerNotExists .= " SELECT cat_cus.fk_soc";
919 $sqlCategoryCustomerNotExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
920 $sqlCategoryCustomerNotExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
921 $sqlCategoryCustomerNotExists .= " )";
922 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerNotExists;
923 } elseif (intval($searchCategoryCustomer) > 0) {
924 $existsCategoryCustomerList[] = $db->escape($searchCategoryCustomer);
925 }
926 }
927 if (!empty($existsCategoryCustomerList)) {
928 $sqlCategoryCustomerExists = " EXISTS (";
929 $sqlCategoryCustomerExists .= " SELECT cat_cus.fk_soc";
930 $sqlCategoryCustomerExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
931 $sqlCategoryCustomerExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
932 $sqlCategoryCustomerExists .= " AND cat_cus.fk_categorie IN (".$db->sanitize(implode(',', $existsCategoryCustomerList)).")";
933 $sqlCategoryCustomerExists .= " )";
934 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerExists;
935 }
936 if (!empty($searchCategoryCustomerSqlList)) {
937 $sql .= " AND (".implode(' OR ', $searchCategoryCustomerSqlList).")";
938 }
939} else {
940 foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
941 if (intval($searchCategoryCustomer) == -2) {
942 $sqlCategoryCustomerNotExists = " NOT EXISTS (";
943 $sqlCategoryCustomerNotExists .= " SELECT cat_cus.fk_soc";
944 $sqlCategoryCustomerNotExists .= " FROM ".$db->prefix()."categorie_societe AS cat_cus";
945 $sqlCategoryCustomerNotExists .= " WHERE cat_cus.fk_soc = p.fk_soc";
946 $sqlCategoryCustomerNotExists .= " )";
947 $searchCategoryCustomerSqlList[] = $sqlCategoryCustomerNotExists;
948 } elseif (intval($searchCategoryCustomer) > 0) {
949 $searchCategoryCustomerSqlList[] = "p.fk_soc IN (SELECT fk_soc FROM ".$db->prefix()."categorie_societe WHERE fk_categorie = ".((int) $searchCategoryCustomer).")";
950 }
951 }
952 if (!empty($searchCategoryCustomerSqlList)) {
953 $sql .= " AND (".implode(' AND ', $searchCategoryCustomerSqlList).")";
954 }
955}
956*/
957
958// Add where from extra fields
959include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
960// Add where from hooks
961$parameters = array();
962$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
963$sql .= $hookmanager->resPrint;
964//print $sql;
965
966// Count total nb of records
967$nbtotalofrecords = '';
968if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
969 /* The fast and low memory method to get and count full list converts the sql into a sql count */
970 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
971 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
972 $resql = $db->query($sqlforcount);
973 if ($resql) {
974 $objforcount = $db->fetch_object($resql);
975 $nbtotalofrecords = $objforcount->nbtotalofrecords;
976 } else {
977 dol_print_error($db);
978 }
979
980 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
981 $page = 0;
982 $offset = 0;
983 }
984 $db->free($resql);
985}
986
987// Complete request and execute it with limit
988$sql .= $db->order($sortfield, $sortorder);
989if ($limit) {
990 $sql .= $db->plimit($limit + 1, $offset);
991}
992//print $sql;
993
994$resql = $db->query($sql);
995if (!$resql) {
996 dol_print_error($db);
997 exit;
998}
999
1000$num = $db->num_rows($resql);
1001
1002// Direct jump if only one record found
1003if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
1004 $obj = $db->fetch_object($resql);
1005 header("Location: ".DOL_URL_ROOT.'/projet/card.php?id='.$obj->id);
1006 exit;
1007}
1008
1009
1010// Output page
1011// --------------------------------------------------------------------
1012
1013$arrayofselected = is_array($toselect) ? $toselect : array();
1014
1015$param = '';
1016if (!empty($mode)) {
1017 $param .= '&mode='.urlencode($mode);
1018}
1019if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
1020 $param .= '&contextpage='.urlencode($contextpage);
1021}
1022if ($limit > 0 && $limit != $conf->liste_limit) {
1023 $param .= '&limit='.((int) $limit);
1024}
1025if ($optioncss != '') {
1026 $param .= '&optioncss='.urlencode($optioncss);
1027}
1028if ($search_all != '') {
1029 $param .= '&search_all='.urlencode($search_all);
1030}
1031if ($search_entity != '') {
1032 $param .= '&search_entity='.((int) $search_entity);
1033}
1034if ($groupby != '') {
1035 $param .= '&groupby='.urlencode($groupby);
1036}
1037
1038if ($search_parent_ref != '') {
1039 $param .= '&search_parent_ref='.urlencode($search_parent_ref);
1040}
1041if ($search_parent_label != '') {
1042 $param .= '&search_parent_label='.urlencode($search_parent_label);
1043}
1044
1045if ($socid) {
1046 $param .= '&socid='.urlencode((string) $socid);
1047}
1048if ($search_sday) {
1049 $param .= '&search_sday='.urlencode((string) ($search_sday));
1050}
1051if ($search_smonth) {
1052 $param .= '&search_smonth='.urlencode((string) ($search_smonth));
1053}
1054if ($search_syear) {
1055 $param .= '&search_syear='.urlencode((string) ($search_syear));
1056}
1057if ($search_eday) {
1058 $param .= '&search_eday='.urlencode((string) ($search_eday));
1059}
1060if ($search_emonth) {
1061 $param .= '&search_emonth='.urlencode((string) ($search_emonth));
1062}
1063if ($search_eyear) {
1064 $param .= '&search_eyear='.urlencode((string) ($search_eyear));
1065}
1066if ($search_date_start_startmonth) {
1067 $param .= '&search_date_start_startmonth='.urlencode((string) ($search_date_start_startmonth));
1068}
1069if ($search_date_start_startyear) {
1070 $param .= '&search_date_start_startyear='.urlencode((string) ($search_date_start_startyear));
1071}
1072if ($search_date_start_startday) {
1073 $param .= '&search_date_start_startday='.urlencode((string) ($search_date_start_startday));
1074}
1075if ($search_date_start_start) {
1076 $param .= '&search_date_start_start='.urlencode((string) $search_date_start_start);
1077}
1078if ($search_date_start_endmonth) {
1079 $param .= '&search_date_start_endmonth='.urlencode((string) ($search_date_start_endmonth));
1080}
1081if ($search_date_start_endyear) {
1082 $param .= '&search_date_start_endyear='.urlencode((string) ($search_date_start_endyear));
1083}
1084if ($search_date_start_endday) {
1085 $param .= '&search_date_start_endday='.urlencode((string) ($search_date_start_endday));
1086}
1087if ($search_date_start_end) {
1088 $param .= '&search_date_start_end='.urlencode($search_date_start_end);
1089}
1090if ($search_date_end_startmonth) {
1091 $param .= '&search_date_end_startmonth='.urlencode((string) ($search_date_end_startmonth));
1092}
1093if ($search_date_end_startyear) {
1094 $param .= '&search_date_end_startyear='.urlencode((string) ($search_date_end_startyear));
1095}
1096if ($search_date_end_startday) {
1097 $param .= '&search_date_end_startday='.urlencode((string) ($search_date_end_startday));
1098}
1099if ($search_date_end_start) {
1100 $param .= '&search_date_end_start='.urlencode((string) $search_date_end_start);
1101}
1102if ($search_date_end_endmonth) {
1103 $param .= '&search_date_end_endmonth='.urlencode((string) ($search_date_end_endmonth));
1104}
1105if ($search_date_end_endyear) {
1106 $param .= '&search_date_end_endyear='.urlencode((string) ($search_date_end_endyear));
1107}
1108if ($search_date_end_endday) {
1109 $param .= '&search_date_end_endday='.urlencode((string) ($search_date_end_endday));
1110}
1111if ($search_date_end_end) {
1112 $param .= '&search_date_end_end=' . urlencode((string) $search_date_end_end);
1113}
1114if ($search_date_creation_startmonth) {
1115 $param .= '&search_date_creation_startmonth='.urlencode((string) ($search_date_creation_startmonth));
1116}
1117if ($search_date_creation_startyear) {
1118 $param .= '&search_date_creation_startyear='.urlencode((string) ($search_date_creation_startyear));
1119}
1120if ($search_date_creation_startday) {
1121 $param .= '&search_date_creation_startday='.urlencode((string) ($search_date_creation_startday));
1122}
1123if ($search_date_creation_start) {
1124 $param .= '&search_date_creation_start='.urlencode((string) $search_date_creation_start);
1125}
1126if ($search_date_creation_endmonth) {
1127 $param .= '&search_date_creation_endmonth='.urlencode((string) ($search_date_creation_endmonth));
1128}
1129if ($search_date_creation_endyear) {
1130 $param .= '&search_date_creation_endyear='.urlencode((string) ($search_date_creation_endyear));
1131}
1132if ($search_date_creation_endday) {
1133 $param .= '&search_date_creation_endday='.urlencode((string) ($search_date_creation_endday));
1134}
1135if ($search_date_creation_end) {
1136 $param .= '&search_date_creation_end='.urlencode($search_date_creation_end);
1137}
1138if ($search_date_modif_startmonth) {
1139 $param .= '&search_date_modif_startmonth='.urlencode((string) ($search_date_modif_startmonth));
1140}
1141if ($search_date_modif_startyear) {
1142 $param .= '&search_date_modif_startyear='.urlencode((string) ($search_date_modif_startyear));
1143}
1144if ($search_date_modif_startday) {
1145 $param .= '&search_date_modif_startday='.urlencode((string) ($search_date_modif_startday));
1146}
1147if ($search_date_modif_start) {
1148 $param .= '&search_date_modif_start='.urlencode((string) $search_date_modif_start);
1149}
1150if ($search_date_modif_endmonth) {
1151 $param .= '&search_date_modif_endmonth='.urlencode((string) ($search_date_modif_endmonth));
1152}
1153if ($search_date_modif_endyear) {
1154 $param .= '&search_date_modif_endyear='.urlencode((string) ($search_date_modif_endyear));
1155}
1156if ($search_date_modif_endday) {
1157 $param .= '&search_date_modif_endday='.urlencode((string) ($search_date_modif_endday));
1158}
1159if ($search_date_modif_end) {
1160 $param .= '&search_date_modif_end=' . urlencode((string) $search_date_modif_end);
1161}
1162if (!empty($search_category_user_array)) {
1163 if ($searchCategoryUserOperator) {
1164 $param .= '&search_category_user_operator='.((int) $searchCategoryUserOperator);
1165 }
1166 foreach ($search_category_user_array as $tmpval) {
1167 $param .= '&search_category_user_list[]='.urlencode($tmpval);
1168 }
1169}
1170if (!empty($search_category_array)) {
1171 if ($searchCategoryProjectOperator) {
1172 $param .= '&search_category_project_operator='.((int) $searchCategoryProjectOperator);
1173 }
1174 foreach ($search_category_array as $tmpval) {
1175 $param .= '&search_category_project_list[]='.urlencode($tmpval);
1176 }
1177}
1178if (!empty($searchCategoryCustomerList)) {
1179 foreach ($searchCategoryCustomerList as $searchCategoryCustomer) {
1180 $param .= "&search_category_customer_list[]=".urlencode($searchCategoryCustomer);
1181 }
1182}
1183if ($search_id != '') {
1184 $param .= '&search_id='.urlencode($search_id);
1185}
1186if ($search_ref != '') {
1187 $param .= '&search_ref='.urlencode($search_ref);
1188}
1189if ($search_label != '') {
1190 $param .= '&search_label='.urlencode($search_label);
1191}
1192if ($search_note_public != '') {
1193 $param .= '&search_note_public='.urlencode($search_note_public);
1194}
1195if ($search_note_private != '') {
1196 $param .= '&search_note_private='.urlencode($search_note_private);
1197}
1198if ($search_societe != '') {
1199 $param .= '&search_societe='.urlencode($search_societe);
1200}
1201if ($search_societe_alias != '') {
1202 $param .= '&search_societe_alias='.urlencode($search_societe_alias);
1203}
1204if ($search_societe_country != '') {
1205 $param .= '&search_societe_country='.urlencode($search_societe_country);
1206}
1207if ($search_societe_ref_customer != '') {
1208 $param .= '&search_societe_ref_customer='.urlencode($search_societe_ref_customer);
1209}
1210if ($search_societe_ref_supplier != '') {
1211 $param .= '&search_societe_ref_supplier='.urlencode($search_societe_ref_supplier);
1212}
1213if ($search_status != '' && $search_status != '-1') {
1214 $param .= "&search_status=".urlencode($search_status);
1215}
1216if ($search_option) {
1217 $param .= "&search_option=".urlencode($search_option);
1218}
1219if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'openedopp', 'notopenedopp', 'none'))) {
1220 $param .= '&search_opp_status='.urlencode($search_opp_status);
1221}
1222if ($search_opp_percent != '') {
1223 $param .= '&search_opp_percent='.urlencode($search_opp_percent);
1224}
1225if ($search_public != '') {
1226 $param .= '&search_public='.urlencode($search_public);
1227}
1228if ($search_project_user > 0) {
1229 $param .= '&search_project_user='.urlencode((string) $search_project_user);
1230}
1231if ($search_project_contact > 0) {
1232 $param .= '&search_project_contact='.urlencode((string) ($search_project_contact));
1233}
1234if ($search_sale > 0) {
1235 $param .= '&search_sale='.urlencode((string) ($search_sale));
1236}
1237if ($search_opp_amount != '') {
1238 $param .= '&search_opp_amount='.urlencode($search_opp_amount);
1239}
1240if ($search_budget_amount != '') {
1241 $param .= '&search_budget_amount='.urlencode($search_budget_amount);
1242}
1243if ($search_usage_opportunity != '') {
1244 $param .= '&search_usage_opportunity='.urlencode($search_usage_opportunity);
1245}
1246if ($search_usage_task != '') {
1247 $param .= '&search_usage_task='.urlencode($search_usage_task);
1248}
1249if ($search_usage_bill_time != '') {
1250 $param .= '&search_usage_bill_time='.urlencode($search_usage_bill_time);
1251}
1252if ($search_usage_event_organization != '') {
1253 $param .= '&search_usage_event_organization='.urlencode($search_usage_event_organization);
1254}
1255if ($search_accept_conference_suggestions != '') {
1256 $param .= '&search_accept_conference_suggestions='.urlencode($search_accept_conference_suggestions);
1257}
1258if ($search_accept_booth_suggestions != '') {
1259 $param .= '&search_accept_booth_suggestions='.urlencode($search_accept_booth_suggestions);
1260}
1261if ($search_price_registration != '') {
1262 $param .= '&search_price_registration='.urlencode($search_price_registration);
1263}
1264if ($search_price_booth != '') {
1265 $param .= '&search_price_booth='.urlencode($search_price_booth);
1266}
1267if ($search_login) {
1268 $param .= '&search_login='.urlencode($search_login);
1269}
1270if ($search_import_key) {
1271 $param .= '&search_import_key='.urlencode($search_import_key);
1272}
1273if ($search_omitChildren) {
1274 $param .= '&search_omitChildren=on';
1275}
1276// Add $param from extra fields
1277include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
1278
1279// Add $param from hooks
1280$parameters = array('param' => &$param);
1281$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1282$param .= $hookmanager->resPrint;
1283
1284// Use Post/Redirect/Get for filter submissions so browser history contains a
1285// reconstructible GET request instead of a POST that requires confirmation.
1286$filterSearchSubmitted = GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha');
1287$filterResetSubmitted = GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha');
1288if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($filterSearchSubmitted || $filterResetSubmitted)) {
1289 $redirectUrl = dolBuildUrl($_SERVER['PHP_SELF'], array(
1290 'formfilteraction' => 'list',
1291 'sortfield' => $sortfield,
1292 'sortorder' => $sortorder,
1293 ));
1294 $redirectUrl .= $param;
1295 if ($filterResetSubmitted && $search_status == -1) {
1296 $redirectUrl .= '&search_status=-1';
1297 }
1298 header('Location: '.$redirectUrl, true, 303);
1299 exit;
1300}
1301
1302llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'mod-project page-list bodyforlist');
1303
1304// List of mass actions available
1305$arrayofmassactions = array(
1306 'validate' => img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
1307 'generate_doc' => img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
1308 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
1309 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
1310);
1311//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
1312if ($user->hasRight('projet', 'creer')) {
1313 $arrayofmassactions['close'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Close");
1314 $arrayofmassactions['preaffectuser'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("AffectUser");
1315}
1316if ($user->hasRight('projet', 'supprimer')) {
1317 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
1318}
1319if (isModEnabled('category') && $user->hasRight('projet', 'creer')) {
1320 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
1321}
1322if (in_array($massaction, array('presend', 'predelete', 'preaffecttag', 'preaffectuser'))) {
1323 $arrayofmassactions = array();
1324}
1325
1326$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
1327
1328$url = DOL_URL_ROOT.'/projet/card.php?action=create';
1329if (!empty($socid)) {
1330 $url .= '&socid='.$socid;
1331}
1332if ($search_usage_event_organization == 1) {
1333 $url .= '&usage_organize_event=1';
1334 if (((int) $search_usage_opportunity) < 1) {
1335 $url .= '&usage_opportunity=0';
1336 }
1337}
1338
1339$newcardbutton = '';
1340$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
1341$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
1342if ($contextpage == 'lead') {
1343 $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanbanGroupBy'), '', 'fa fa-grip-vertical imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanbangroupby&groupby=p.fk_opp_status'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'kanbangroupby' ? 2 : 1), array('morecss' => 'reposition'));
1344}
1345$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', DOL_URL_ROOT.'/projet/stats/index.php?mode=statistics&contextpage='.$contextpage.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'statistics' ? 2 : 1), array('morecss' => 'reposition'));
1346$newcardbutton .= dolGetButtonTitleSeparator();
1347$newcardbutton .= dolGetButtonTitle($langs->trans('NewProject'), '', 'fa fa-plus-circle', $url, '', $user->hasRight('projet', 'creer'));
1348
1349print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
1350if ($optioncss != '') {
1351 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
1352}
1353print '<input type="hidden" name="token" value="'.newToken().'">';
1354print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
1355print '<input type="hidden" name="action" value="list">';
1356print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
1357print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
1358print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
1359print '<input type="hidden" name="mode" value="'.$mode.'">';
1360print '<input type="hidden" name="groupby" value="'.$groupby.'">';
1361
1362// Show description of content
1363$htmltooltip = '';
1364if ($search_project_user == $user->id) {
1365 $htmltooltip .= $langs->trans("MyProjectsDesc");
1366} else {
1367 if ($user->hasRight('projet', 'all', 'lire') && !$socid) {
1368 $htmltooltip .= $langs->trans("ProjectsDesc");
1369 } else {
1370 $htmltooltip .= $langs->trans("ProjectsPublicDesc");
1371 }
1372}
1373
1374print_barre_liste($form->textwithpicto($title, $htmltooltip), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'project', 0, $newcardbutton, '', $limit, 0, 0, 1);
1375
1376
1377$topicmail = "Information";
1378$modelmail = "project";
1379$objecttmp = new Project($db);
1380$trackid = 'proj'.$object->id;
1381include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
1382
1383if ($search_all) {
1384 foreach ($fieldstosearchall as $key => $val) {
1385 $fieldstosearchall[$key] = $langs->trans($val);
1386 }
1387 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
1388}
1389
1390$moreforfilter = '';
1391
1392// If the user can view user other than himself
1393$moreforfilter .= '<div class="divsearchfield">';
1394$tmptitle = $langs->trans('ProjectsWithThisUserAsContact');
1395//$includeonly = 'hierarchyme';
1396$includeonly = '';
1397if (!$user->hasRight('user', 'user', 'lire')) {
1398 $includeonly = array($user->id);
1399}
1400$moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', $tmptitle, null, 0, $includeonly, '', '0', 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
1401$moreforfilter .= '</div>';
1402
1403// Filter on user categories
1404if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
1405 $langs->load("categories");
1406 $formcategory = new FormCategory($db);
1407 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_USER, $search_category_user_array, 'minwidth200imp minwidth200 widthcentpercentminusx', -1, 1, 1, $langs->transnoentitiesnoconv("UsersCategoryShort"));
1408}
1409
1410
1411$moreforfilter .= '<div class="divsearchfield">';
1412$tmptitle = $langs->trans('ProjectsWithThisContact');
1413$moreforfilter .= img_picto($tmptitle, 'contact', 'class="pictofixedwidth"').$form->select_contact(0, $search_project_contact ? $search_project_contact : '', 'search_project_contact', $tmptitle, '', '', 0, 'maxwidth300 widthcentpercentminusx');
1414
1415$moreforfilter .= '</div>';
1416
1417// If the user can view thirdparties other than his', we offer the filter assigned to
1418// TODO This must be moved on the dedicated column "Assigned to".
1419if ($user->hasRight('user', 'user', 'lire')) {
1420 $langs->load("commercial");
1421 $moreforfilter .= '<div class="divsearchfield">';
1422 $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative');
1423 $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth300 widthcentpercentminusx');
1424 $moreforfilter .= '</div>';
1425}
1426
1427// Filter on project categories
1428if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
1429 $formcategory = new FormCategory($db);
1430 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PROJECT, $search_category_array, 'minwidth200imp minwidth200 widthcentpercentminusx', -1, 1, 1, $langs->transnoentitiesnoconv("ProjectsCategoryShort"));
1431}
1432
1433// Filter on customer categories
1434if (getDolGlobalString('MAIN_SEARCH_CATEGORY_CUSTOMER_ON_PROJECT_LIST') && isModEnabled("category") && $user->hasRight('categorie', 'lire')) {
1435 $formcategory = new FormCategory($db);
1436 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_CUSTOMER, $searchCategoryCustomerList, 'minwidth200imp minwidth200 widthcentpercentminusx', $searchCategoryCustomerList ? $searchCategoryCustomerList : 0);
1437}
1438
1439// alert on late date
1440$moreforfilter .= '<div class="divsearchfield">';
1441$moreforfilter .= '<label for="search_option" title="'.$langs->trans("Late").'">'.$langs->trans('Alert').' </label><input type="checkbox" id="search_option" name="search_option" value="late"'.($search_option == 'late' ? ' checked' : '').'>';
1442$moreforfilter .= '</div>';
1443
1444if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1445 //Checkbox for omitting child projects filter
1446 $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"' : '').'"> ';
1447}
1448
1449if (!empty($moreforfilter)) {
1450 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1451 print $moreforfilter;
1452 $parameters = array();
1453 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1454 print $hookmanager->resPrint;
1455 print '</div>';
1456}
1457
1458$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
1459$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
1460$selectedfields = (($mode != 'kanban' && $mode != 'kanbangroupby') ? $htmlofselectarray : '');
1461$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
1462
1463
1464print '<div class="div-table-responsive">';
1465print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
1466
1467// Fields title search
1468// --------------------------------------------------------------------
1469print '<thead>';
1470print '<tr class="liste_titre_filter">';
1471// Action column left
1472if ($conf->main_checkbox_left_column) {
1473 print '<td class="liste_titre center maxwidthsearch" id="action_column_left">';
1474 $searchpicto = $form->showFilterButtons('left');
1475 print $searchpicto;
1476 print '</td>';
1477}
1478// Project ID
1479if (!empty($arrayfields['p.rowid']['checked'])) {
1480 print '<td class="liste_titre" id="search_id">';
1481 print '<input type="text" class="flat width50" name="search_id" value="'.dol_escape_htmltag($search_id).'">';
1482 print '</td>';
1483}
1484// Project ref
1485if (!empty($arrayfields['p.ref']['checked'])) {
1486 print '<td class="liste_titre" id="search_ref">';
1487 print '<input type="text" class="flat width75" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
1488 print '</td>';
1489}
1490// Project label
1491if (!empty($arrayfields['p.title']['checked'])) {
1492 print '<td class="liste_titre" id="search_label">';
1493 print '<input type="text" class="flat width100" name="search_label" value="'.dol_escape_htmltag($search_label).'">';
1494 print '</td>';
1495}
1496
1497// Parent project
1498if (!empty($arrayfields['p.fk_project']['checked'])) {
1499 print '<td class="liste_titre" id="parent_project">';
1500 print '<div class="nowrap">';
1501 $ref_placeholder = $langs->trans('Ref');
1502 print '<input id="search_parent_ref" placeholder="'.$ref_placeholder.'" type="text" class="flat width75" name="search_parent_ref" value="'.dol_escape_htmltag($search_parent_ref).'">';
1503 print '</div>';
1504 print '<div class="nowrap">';
1505 $label_placeholder = $langs->trans('Label');
1506 print '<input id="search_parent_label" placeholder="'.$label_placeholder.'" type="text" class="flat width75" name="search_parent_label" value="'.dol_escape_htmltag($search_parent_label).'">';
1507 print '</div>';
1508 print '</td>';
1509}
1510
1511// Third party
1512if (!empty($arrayfields['s.nom']['checked'])) {
1513 print '<td class="liste_titre" id="search_societe">';
1514 if ($socid > 0) {
1515 $tmpthirdparty = new Societe($db);
1516 $tmpthirdparty->fetch($socid);
1517 $search_societe = $tmpthirdparty->name;
1518 }
1519 print '<input type="text" class="flat width100" name="search_societe" value="'.dol_escape_htmltag((string) $search_societe).'">';
1520 print '</td>';
1521}
1522
1523// Alias
1524if (!empty($arrayfields['s.name_alias']['checked'])) {
1525 print '<td class="liste_titre" id="search_societe_alias">';
1526 if ($socid > 0) {
1527 $tmpthirdparty = new Societe($db);
1528 $tmpthirdparty->fetch($socid);
1529 $search_societe_alias = $tmpthirdparty->name_alias;
1530 }
1531 print '<input type="text" class="flat width100" name="search_societe_alias" value="'.dol_escape_htmltag($search_societe_alias).'">';
1532 print '</td>';
1533}
1534
1535// Ref customer
1536if (!empty($arrayfields['s.code_client']['checked'])) {
1537 print '<td class="liste_titre" id="search_societe_ref_customer">';
1538 print '<input type="text" class="flat width75" name="search_societe_ref_customer" value="'.dol_escape_htmltag($search_societe_ref_customer).'">';
1539 print '</td>';
1540}
1541// Ref supplier
1542if (!empty($arrayfields['s.code_fournisseur']['checked'])) {
1543 print '<td class="liste_titre" id="search_societe_ref_supplier">';
1544 print '<input type="text" class="flat width75" name="search_societe_ref_supplier" value="'.dol_escape_htmltag($search_societe_ref_supplier).'">';
1545 print '</td>';
1546}
1547
1548// Country of thirdparty
1549if (!empty($arrayfields['co.country_code']['checked'])) {
1550 print '<td class="liste_titre" id="search_societe_country">';
1551 print '<input type="text" class="flat width50" name="search_societe_country" value="'.dol_escape_htmltag($search_societe_country).'">';
1552 print '</td>';
1553}
1554// Sale representative
1555if (!empty($arrayfields['commercial']['checked'])) {
1556 print '<td class="liste_titre" id="sale_representative">&nbsp;</td>';
1557}
1558// Start date
1559if (!empty($arrayfields['p.dateo']['checked'])) {
1560 print '<td class="liste_titre center" id="search_date_start">';
1561 print '<div class="nowrapfordate">';
1562 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'));
1563 print '</div>';
1564 print '<div class="nowrapfordate">';
1565 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'));
1566 print '</div>';
1567 print '</td>';
1568}
1569// End date
1570if (!empty($arrayfields['p.datee']['checked'])) {
1571 print '<td class="liste_titre center" id="search_date_end">';
1572 print '<div class="nowrapfordate">';
1573 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'));
1574 print '</div>';
1575 print '<div class="nowrapfordate">';
1576 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'));
1577 print '</div>';
1578 print '</td>';
1579}
1580// Visibility
1581if (!empty($arrayfields['p.public']['checked'])) {
1582 print '<td class="liste_titre center">';
1583 $array = array('' => '', 0 => $langs->trans("PrivateProject"), 1 => $langs->trans("SharedProject"));
1584 print $form->selectarray('search_public', $array, $search_public, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth75');
1585 print '</td>';
1586}
1587if (!empty($arrayfields['c.assigned']['checked'])) {
1588 print '<td class="liste_titre center">';
1589 print '</td>';
1590}
1591// Opp status
1592if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
1593 print '<td class="liste_titre nowrap center">';
1594 print $formproject->selectOpportunityStatus('search_opp_status', $search_opp_status, 1, 1, 1, 0, 'maxwidth125 nowrapoption', 1, 1);
1595 print '</td>';
1596}
1597if (!empty($arrayfields['p.opp_amount']['checked'])) {
1598 print '<td class="liste_titre nowrap right" id="search_opp_amount">';
1599 print '<input type="text" class="flat" name="search_opp_amount" size="3" value="'.$search_opp_amount.'">';
1600 print '</td>';
1601}
1602if (!empty($arrayfields['p.opp_percent']['checked'])) {
1603 print '<td class="liste_titre nowrap right" id="search_opp_percent">';
1604 print '<input type="text" class="flat" name="search_opp_percent" size="2" value="'.$search_opp_percent.'">';
1605 print '</td>';
1606}
1607if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
1608 print '<td class="liste_titre nowrap right">';
1609 print '</td>';
1610}
1611if (!empty($arrayfields['p.budget_amount']['checked'])) {
1612 print '<td class="liste_titre nowrap right" id="search_budget_amount">';
1613 print '<input type="text" class="flat" name="search_budget_amount" size="4" value="'.$search_budget_amount.'">';
1614 print '</td>';
1615}
1616if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
1617 print '<td class="liste_titre nowrap">';
1618 print $form->selectyesno('search_usage_opportunity', $search_usage_opportunity, 1, false, 1, 1);
1619 print '';
1620 print '</td>';
1621}
1622if (!empty($arrayfields['p.usage_task']['checked'])) {
1623 print '<td class="liste_titre nowrap">';
1624 print $form->selectyesno('search_usage_task', $search_usage_task, 1, false, 1, 1);
1625 print '</td>';
1626}
1627if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
1628 print '<td class="liste_titre nowrap">';
1629 print $form->selectyesno('search_usage_bill_time', $search_usage_bill_time, 1, false, 1, 1);
1630 print '</td>';
1631}
1632if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
1633 print '<td class="liste_titre nowrap">';
1634 print $form->selectyesno('search_usage_event_organization', $search_usage_event_organization, 1, false, 1, 1);
1635 print '</td>';
1636}
1637if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
1638 print '<td class="liste_titre nowrap">';
1639 print $form->selectyesno('search_accept_conference_suggestions', $search_accept_conference_suggestions, 1, false, 1, 1);
1640 print '</td>';
1641}
1642if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
1643 print '<td class="liste_titre nowrap">';
1644 print $form->selectyesno('search_accept_booth_suggestions', $search_accept_booth_suggestions, 1, false, 1, 1);
1645 print '</td>';
1646}
1647if (!empty($arrayfields['p.price_registration']['checked'])) {
1648 print '<td class="liste_titre nowrap right" id="search_price_registration">';
1649 print '<input type="text" class="flat" name="search_price_registration" size="4" value="'.dol_escape_htmltag($search_price_registration).'">';
1650 print '</td>';
1651}
1652if (!empty($arrayfields['p.price_booth']['checked'])) {
1653 print '<td class="liste_titre nowrap right" id="search_price_booth">';
1654 print '<input type="text" class="flat" name="search_price_booth" size="4" value="'.dol_escape_htmltag($search_price_booth).'">';
1655 print '</td>';
1656}
1657if (!empty($arrayfields['u.login']['checked'])) {
1658 // Author
1659 print '<td class="liste_titre" align="center" id="search_login">';
1660 print '<input class="flat" size="4" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'">';
1661 print '</td>';
1662}
1663if (!empty($arrayfields['p.note_public']['checked'])) {
1664 print '<td class="liste_titre">';
1665 print '<input class="flat width75" type="text" name="search_note_public" value="'.dolPrintHTMLForAttribute($search_note_public).'">';
1666 print '</td>';
1667}
1668if (!empty($arrayfields['p.note_private']['checked'])) {
1669 print '<td class="liste_titre">';
1670 print '<input class="flat width75" type="text" name="search_note_private" value="'.dolPrintHTMLForAttribute($search_note_private).'">';
1671 print '</td>';
1672}
1673// Extra fields
1674include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1675
1676// Fields from hook
1677$parameters = array('arrayfields' => $arrayfields);
1678$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
1679print $hookmanager->resPrint;
1680// Creation date
1681if (!empty($arrayfields['p.datec']['checked'])) {
1682 print '<td class="liste_titre center" id="search_date_creation">';
1683 print '<div class="nowrapfordate">';
1684 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'));
1685 print '</div>';
1686 print '<div class="nowrapfordate">';
1687 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'));
1688 print '</div>';
1689 print '</td>';
1690}
1691// Modification date
1692if (!empty($arrayfields['p.tms']['checked'])) {
1693 print '<td class="liste_titre center" id="search_date_modif">';
1694 print '<div class="nowrapfordate">';
1695 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'));
1696 print '</div>';
1697 print '<div class="nowrapfordate">';
1698 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'));
1699 print '</div>';
1700 print '</td>';
1701}
1702if (!empty($arrayfields['p.email_msgid']['checked'])) {
1703 // Email msg id
1704 print '<td class="liste_titre">';
1705 print '</td>';
1706}
1707if (!empty($arrayfields['p.import_key']['checked'])) {
1708 // Import key
1709 print '<td class="liste_titre" id="search_import_key">';
1710 print '<input class="flat width75" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
1711 print '</td>';
1712}
1713// Status - if you insert id here it doesn't work the way it should - so we don't
1714if (!empty($arrayfields['p.fk_statut']['checked'])) {
1715 print '<td class="liste_titre center parentonrightofpage">';
1716 $formproject->selectProjectsStatus($search_status, 1, 'search_status');
1717 print '</td>';
1718}
1719// Action column right
1720if (!$conf->main_checkbox_left_column) {
1721 print '<td class="liste_titre maxwidthsearch" id="action_column_right">';
1722 $searchpicto = $form->showFilterButtons();
1723 print $searchpicto;
1724 print '</td>';
1725}
1726print '</tr>'."\n";
1727
1728$totalarray = array();
1729$totalarray['nbfield'] = 0;
1730
1731// Fields title label
1732// --------------------------------------------------------------------
1733print '<tr class="liste_titre">';
1734if ($conf->main_checkbox_left_column) {
1735 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1736 $totalarray['nbfield']++;
1737}
1738if (!empty($arrayfields['p.rowid']['checked'])) {
1739 print_liste_field_titre($arrayfields['p.rowid']['label'], $_SERVER["PHP_SELF"], "p.rowid", "", $param, "", $sortfield, $sortorder);
1740 $totalarray['nbfield']++;
1741}
1742if (!empty($arrayfields['p.ref']['checked'])) {
1743 print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
1744 $totalarray['nbfield']++;
1745}
1746if (!empty($arrayfields['p.title']['checked'])) {
1747 print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER["PHP_SELF"], "p.title", "", $param, "", $sortfield, $sortorder);
1748 $totalarray['nbfield']++;
1749}
1750if (!empty($arrayfields['p.fk_project']['checked'])) {
1751 print_liste_field_titre($arrayfields['p.fk_project']['label'], $_SERVER["PHP_SELF"], "p.fk_project", "", $param, "", $sortfield, $sortorder);
1752 $totalarray['nbfield']++;
1753}
1754if (!empty($arrayfields['s.nom']['checked'])) {
1755 print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder);
1756 $totalarray['nbfield']++;
1757}
1758if (!empty($arrayfields['s.name_alias']['checked'])) {
1759 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1760 print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER["PHP_SELF"], "s.name_alias", "", $param, "", $sortfield, $sortorder);
1761 $totalarray['nbfield']++;
1762}
1763if (!empty($arrayfields['s.code_client']['checked'])) {
1764 print_liste_field_titre($arrayfields['s.code_client']['label'], $_SERVER["PHP_SELF"], "s.code_client", "", $param, "", $sortfield, $sortorder);
1765 $totalarray['nbfield']++;
1766}
1767if (!empty($arrayfields['s.code_fournisseur']['checked'])) {
1768 print_liste_field_titre($arrayfields['s.code_fournisseur']['label'], $_SERVER["PHP_SELF"], "s.code_fournisseur", "", $param, "", $sortfield, $sortorder);
1769 $totalarray['nbfield']++;
1770}
1771if (!empty($arrayfields['co.country_code']['checked'])) {
1772 print_liste_field_titre($arrayfields['co.country_code']['label'], $_SERVER["PHP_SELF"], "country.code", "", $param, "", $sortfield, $sortorder, 'center ');
1773 $totalarray['nbfield']++;
1774}
1775if (!empty($arrayfields['commercial']['checked'])) {
1776 print_liste_field_titre($arrayfields['commercial']['label'], $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder, 'tdoverflowmax100imp ');
1777 $totalarray['nbfield']++;
1778}
1779if (!empty($arrayfields['p.dateo']['checked'])) {
1780 print_liste_field_titre($arrayfields['p.dateo']['label'], $_SERVER["PHP_SELF"], "p.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
1781 $totalarray['nbfield']++;
1782}
1783if (!empty($arrayfields['p.datee']['checked'])) {
1784 print_liste_field_titre($arrayfields['p.datee']['label'], $_SERVER["PHP_SELF"], "p.datee", "", $param, '', $sortfield, $sortorder, 'center ');
1785 $totalarray['nbfield']++;
1786}
1787if (!empty($arrayfields['p.public']['checked'])) {
1788 print_liste_field_titre($arrayfields['p.public']['label'], $_SERVER["PHP_SELF"], "p.public", "", $param, "", $sortfield, $sortorder, 'center ');
1789 $totalarray['nbfield']++;
1790}
1791if (!empty($arrayfields['c.assigned']['checked'])) {
1792 print_liste_field_titre($arrayfields['c.assigned']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '');
1793 $totalarray['nbfield']++;
1794}
1795if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
1796 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1797 print_liste_field_titre($arrayfields['p.fk_opp_status']['label'], $_SERVER["PHP_SELF"], 'p.fk_opp_status', "", $param, '', $sortfield, $sortorder, 'center ');
1798 $totalarray['nbfield']++;
1799}
1800if (!empty($arrayfields['p.opp_amount']['checked'])) {
1801 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1802 print_liste_field_titre($arrayfields['p.opp_amount']['label'], $_SERVER["PHP_SELF"], 'p.opp_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1803 $totalarray['nbfield']++;
1804}
1805if (!empty($arrayfields['p.opp_percent']['checked'])) {
1806 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1807 print_liste_field_titre($arrayfields['p.opp_percent']['label'], $_SERVER['PHP_SELF'], 'p.opp_percent', "", $param, '', $sortfield, $sortorder, 'right ');
1808 $totalarray['nbfield']++;
1809}
1810if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
1811 print_liste_field_titre($arrayfields['opp_weighted_amount']['label'], $_SERVER['PHP_SELF'], 'opp_weighted_amount', '', $param, '', $sortfield, $sortorder, 'right ');
1812 $totalarray['nbfield']++;
1813}
1814if (!empty($arrayfields['p.budget_amount']['checked'])) {
1815 print_liste_field_titre($arrayfields['p.budget_amount']['label'], $_SERVER["PHP_SELF"], 'p.budget_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1816 $totalarray['nbfield']++;
1817}
1818if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
1819 print_liste_field_titre($arrayfields['p.usage_opportunity']['label'], $_SERVER["PHP_SELF"], 'p.usage_opportunity', "", $param, '', $sortfield, $sortorder, '');
1820 $totalarray['nbfield']++;
1821}
1822if (!empty($arrayfields['p.usage_task']['checked'])) {
1823 print_liste_field_titre($arrayfields['p.usage_task']['label'], $_SERVER["PHP_SELF"], 'p.usage_task', "", $param, '', $sortfield, $sortorder, '');
1824 $totalarray['nbfield']++;
1825}
1826if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
1827 print_liste_field_titre($arrayfields['p.usage_bill_time']['label'], $_SERVER["PHP_SELF"], 'p.usage_bill_time', "", $param, '', $sortfield, $sortorder, '');
1828 $totalarray['nbfield']++;
1829}
1830if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
1831 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1832 print_liste_field_titre($arrayfields['p.usage_organize_event']['label'], $_SERVER["PHP_SELF"], 'p.usage_organize_event', "", $param, '', $sortfield, $sortorder, '');
1833 $totalarray['nbfield']++;
1834}
1835if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
1836 print_liste_field_titre($arrayfields['p.accept_conference_suggestions']['label'], $_SERVER["PHP_SELF"], 'p.accept_conference_suggestions', "", $param, '', $sortfield, $sortorder, '');
1837 $totalarray['nbfield']++;
1838}
1839if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
1840 print_liste_field_titre($arrayfields['p.accept_booth_suggestions']['label'], $_SERVER["PHP_SELF"], 'p.accept_booth_suggestions', "", $param, '', $sortfield, $sortorder, '');
1841 $totalarray['nbfield']++;
1842}
1843if (!empty($arrayfields['p.price_registration']['checked'])) {
1844 print_liste_field_titre($arrayfields['p.price_registration']['label'], $_SERVER["PHP_SELF"], 'p.price_registration', "", $param, '', $sortfield, $sortorder, 'right ');
1845 $totalarray['nbfield']++;
1846}
1847if (!empty($arrayfields['p.price_booth']['checked'])) {
1848 print_liste_field_titre($arrayfields['p.price_booth']['label'], $_SERVER["PHP_SELF"], 'p.price_booth', "", $param, '', $sortfield, $sortorder, 'right ');
1849 $totalarray['nbfield']++;
1850}
1851if (!empty($arrayfields['u.login']['checked'])) {
1852 print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder);
1853 $totalarray['nbfield']++;
1854}
1855if (!empty($arrayfields['p.note_public']['checked'])) {
1856 print_liste_field_titre($arrayfields['p.note_public']['label'], $_SERVER["PHP_SELF"], "p.note_public", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1857 $totalarray['nbfield']++;
1858}
1859if (!empty($arrayfields['p.note_private']['checked'])) {
1860 print_liste_field_titre($arrayfields['p.note_private']['label'], $_SERVER["PHP_SELF"], "p.note_private", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1861 $totalarray['nbfield']++;
1862}
1863// Extra fields
1864include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1865// Hook fields
1866$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
1867$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1868print $hookmanager->resPrint;
1869if (!empty($arrayfields['p.datec']['checked'])) {
1870 print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1871 $totalarray['nbfield']++;
1872}
1873if (!empty($arrayfields['p.tms']['checked'])) {
1874 print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1875 $totalarray['nbfield']++;
1876}
1877if (!empty($arrayfields['p.email_msgid']['checked'])) {
1878 print_liste_field_titre($arrayfields['p.email_msgid']['label'], $_SERVER["PHP_SELF"], "p.email_msgid", "", $param, '', $sortfield, $sortorder, 'center ');
1879 $totalarray['nbfield']++;
1880}
1881if (!empty($arrayfields['p.import_key']['checked'])) {
1882 print_liste_field_titre($arrayfields['p.import_key']['label'], $_SERVER["PHP_SELF"], "p.import_key", "", $param, '', $sortfield, $sortorder, '');
1883 $totalarray['nbfield']++;
1884}
1885if (!empty($arrayfields['p.fk_statut']['checked'])) {
1886 print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'center ');
1887 $totalarray['nbfield']++;
1888}
1889// Action column
1890if (!$conf->main_checkbox_left_column) {
1891 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1892 $totalarray['nbfield']++;
1893}
1894print '</tr></thead>'."\n";
1895
1896
1897$i = 0;
1898$savnbfield = $totalarray['nbfield'];
1899$totalarray = array(
1900 'nbfield' => 0,
1901 'val' => array()
1902);
1903$imaxinloop = ($limit ? min($num, $limit) : $num);
1904while ($i < $imaxinloop) {
1905 $obj = $db->fetch_object($resql);
1906 if (empty($obj)) {
1907 break; // Should not happen
1908 }
1909
1910 // Thirdparty
1911 $companystatic->id = $obj->socid;
1912 $companystatic->name = $obj->name;
1913 $companystatic->name_alias = $obj->alias;
1914 $companystatic->client = $obj->client;
1915 $companystatic->code_client = $obj->code_client;
1916 $companystatic->code_fournisseur = $obj->code_fournisseur;
1917 $companystatic->email = $obj->email;
1918 $companystatic->phone = $obj->phone;
1919 $companystatic->address = $obj->address;
1920 $companystatic->zip = $obj->zip;
1921 $companystatic->town = $obj->town;
1922 $companystatic->country_code = $obj->country_code;
1923
1924 // Project
1925 $object->id = $obj->id;
1926 $object->ref = $obj->ref;
1927 $object->title = $obj->title;
1928 $object->fk_project = $obj->fk_project;
1929 $object->fk_opp_status = $obj->fk_opp_status;
1930 $object->user_author_id = $obj->fk_user_creat;
1931 $object->date_creation = $db->jdate($obj->date_creation);
1932 $object->date_start = $db->jdate($obj->date_start);
1933 $object->date_end = $db->jdate($obj->date_end);
1934 $object->status = $obj->status;
1935 $object->public = $obj->public;
1936 $object->opp_percent = $obj->opp_percent;
1937 $object->opp_status = $obj->fk_opp_status;
1938 $object->opp_status_code = $obj->opp_status_code;
1939 $object->opp_amount = !empty($obj->opp_amount) ? $obj->opp_amount : "";
1940 $object->opp_weighted_amount = $obj->opp_weighted_amount;
1941 $object->budget_amount = $obj->budget_amount;
1942 $object->usage_opportunity = $obj->usage_opportunity;
1943 $object->usage_task = $obj->usage_task;
1944 $object->usage_bill_time = $obj->usage_bill_time;
1945 $object->usage_organize_event = $obj->usage_organize_event;
1946 $object->email_msgid = $obj->email_msgid;
1947 $object->import_key = $obj->import_key;
1948 $object->note_public = $obj->note_public;
1949 $object->note_private = $obj->note_private;
1950 $object->thirdparty = $companystatic;
1951
1952 //$userAccess = $object->restrictedProjectArea($user); // disabled, permission on project must be done by the select
1953
1954 $stringassignedusers = '';
1955
1956 if (!empty($arrayfields['c.assigned']['checked'])) {
1957 $ifisrt = 1;
1958 foreach (array('internal', 'external') as $source) {
1959 $tab = $object->liste_contact(-1, $source, 0, '', 1);
1960 $numcontact = count($tab);
1961 if (!empty($numcontact)) {
1962 foreach ($tab as $contactproject) {
1963 //var_dump($contacttask);
1964 if ($source == 'internal') {
1965 if (!empty($conf->cache['user'][$contactproject['id']])) {
1966 $c = $conf->cache['user'][$contactproject['id']];
1967 } else {
1968 $c = new User($db);
1969 $c->fetch($contactproject['id']);
1970 $conf->cache['user'][$contactproject['id']] = $c;
1971 }
1972 } else {
1973 if (!empty($conf->cache['contact'][$contactproject['id']])) {
1974 $c = $conf->cache['contact'][$contactproject['id']];
1975 } else {
1976 $c = new Contact($db);
1977 $c->fetch($contactproject['id']);
1978 $conf->cache['contact'][$contactproject['id']] = $c;
1979 }
1980 }
1981 if (get_class($c) == 'User') {
1982 $stringassignedusers .= $c->getNomUrl(-2, '', 0, 0, 24, 1, '', 'valignmiddle'.($ifisrt ? '' : ' notfirst'));
1983 } else {
1984 $stringassignedusers .= $c->getNomUrl(-2, '', 0, 0, -1, 0, 'valignmiddle'.($ifisrt ? '' : ' notfirst'));
1985 }
1986 $ifisrt = 0;
1987 }
1988 }
1989 }
1990 }
1991
1992 if ($mode == 'kanban' || $mode == 'kanbangroupby') {
1993 if ($i == 0) {
1994 print '<tr class="trkanban'.(empty($groupby) ? '' : ' trkanbangroupby').'"><td colspan="'.$savnbfield.'">';
1995 }
1996
1997 $groupbyvalue = 'unset';
1998 $groupbyfield = 'unsetfield';
1999 //var_dump($groupbyvalues);
2000
2001 if (!empty($groupby)) {
2002 $groupbyfield = preg_replace('/^[a-z]+\./', '', $groupby);
2003 // $groupbyold will be the value after the first pass to find break on the next pass.
2004 //var_dump("groupby=$groupby groupbyvalue=$groupbyvalue groupbyfield=$groupbyfield");
2005
2006 if (is_null($groupbyold)) {
2007 print '<div class="box-flex-container-columns kanban">'; // Start div for all kanban columns
2008 }
2009 // Start kanban column
2010 if (is_null($obj->$groupbyfield)) {
2011 $groupbyvalue = 'undefined';
2012 // We found a null value, we add an undefined value in dictionary of values $groupbyvalues
2013 $groupbyvalues[0] = array('id' => '0', 'label' => 'Undefined');
2014 } else {
2015 $groupbyvalue = $obj->$groupbyfield;
2016 }
2017
2018 if ($groupbyold !== $groupbyvalue) { // We found a break on a new column
2019 if (!is_null($groupbyold)) {
2020 print '</div>'; // We need a new kanban column - end box-flex-container
2021 }
2022
2023 $indexofgroupbyvalue = null;
2024
2025 // We show column that we must show before the first current record
2026 //var_dump("groupbyold=".$groupbyold.", current record to show has group value groupbyvalue=".$groupbyvalue);
2027 foreach ($groupbyvalues as $tmpcursor => $tmpgroupbyvalue) { // $tmpcursor is a i index like 0, 1, 2, ...
2028 // Is $tmpcursor a key before, equal or after the $groupbyvalue into the $groupbyvalues
2029 foreach ($groupbyvalues as $tmpcursor2 => $tmpgroupbyvalue2) {
2030 if ($tmpgroupbyvalue2['id'] == $groupbyvalue) { // We found the index of $groupbyvalue
2031 $indexofgroupbyvalue = $tmpcursor2;
2032 break;
2033 }
2034 }
2035 //var_dump('indexofgroupbyvalue='.$indexofgroupbyvalue);
2036
2037 if (!is_null($groupbyold)) {
2038 $indexofgroupbyold = null;
2039 foreach ($groupbyvalues as $tmpcursor2 => $tmpgroupbyvalue2) {
2040 if ($tmpgroupbyvalue2['id'] == $groupbyold) { // We found the index of $groupbyold
2041 $indexofgroupbyold = $tmpcursor2;
2042 break;
2043 }
2044 }
2045 //var_dump('indexofgroupbyold='.$indexofgroupbyold);
2046
2047 if ($tmpcursor <= $indexofgroupbyold) {
2048 continue;
2049 }
2050 }
2051 if ($tmpcursor >= $indexofgroupbyvalue) { // We reach the column to show, so we stop
2052 continue;
2053 }
2054
2055 // We found a possible column with no value, we output the empty column
2056 print '<!-- empty column before column of fetched value --><div class="box-flex-container-column kanban column';
2057 if (array_key_exists($tmpcursor, $groupofcollpasedvalues)) {
2058 print ' kanbancollapsed';
2059 }
2060 print '" data-groupbyid="'.preg_replace('/[^a-z0-9]/', '', $tmpgroupbyvalue['id']).'" data-groupbyfield="'.$groupbyfield.'">';
2061 print '<div class="kanbanlabel">'.$langs->trans($tmpgroupbyvalue['label']).'</div>';
2062 print '</div>'; // Start and end the new column
2063 }
2064
2065 print '<!-- start column for value --><div class="box-flex-container-column kanban column" data-groupbyid="'.preg_replace('/[^a-z0-9]/i', '', $groupbyvalue).'" data-groupbyfield="'.$groupbyfield.'">'; // Start new column
2066 print '<div class="kanbanlabel">'.$langs->trans((is_null($indexofgroupbyvalue) || empty($groupbyvalues[$indexofgroupbyvalue]['label'])) ? 'Undefined' : $groupbyvalues[$indexofgroupbyvalue]['label']).'</div>';
2067 }
2068 $groupbyold = $groupbyvalue;
2069 } elseif ($i == 0) {
2070 print '<div class="box-flex-container kanban">';
2071 }
2072
2073 // Output Kanban
2074 $selected = -1;
2075 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2076 $selected = 0;
2077 if (in_array($object->id, $arrayofselected)) {
2078 $selected = 1;
2079 }
2080 }
2081 $arrayofdata = array('assignedusers' => $stringassignedusers, 'thirdparty' => $companystatic, 'selected' => $selected, 'mode' => $mode);
2082
2083 print $object->getKanbanView('', $arrayofdata, ($groupby ? 'small' : ''));
2084
2085 // if no more elements to show
2086 if ($i == ($imaxinloop - 1)) {
2087 // Close kanban column
2088 if (!empty($groupby)) {
2089 print '</div>'; // end box-flex-container
2090
2091 // We show column that we must show after the last current record
2092 //var_dump("groupbyold=".$groupbyold.", current record to show has group value groupbyvalue=".$groupbyvalue);
2093 foreach ($groupbyvalues as $tmpcursor => $tmpgroupbyvalue) {
2094 // Is $tmpcursor a key before, equal or after the $groupbyvalue into the $groupbyvalues
2095 $indexofgroupbyvalue = null;
2096 foreach ($groupbyvalues as $tmpcursor2 => $tmpgroupbyvalue2) {
2097 if ($tmpgroupbyvalue2['id'] == $groupbyvalue) { // We found the index of $groupbyvalue
2098 $indexofgroupbyvalue = $tmpcursor2;
2099 break;
2100 }
2101 }
2102 //var_dump('indexofgroupbyvalue='.$indexofgroupbyvalue);
2103
2104 if (!is_null($groupbyold)) {
2105 $indexofgroupbyold = null;
2106 foreach ($groupbyvalues as $tmpcursor2 => $tmpgroupbyvalue2) {
2107 if ($tmpgroupbyvalue2['id'] == $groupbyold) { // We found the index of $groupbyold
2108 $indexofgroupbyold = $tmpcursor2;
2109 break;
2110 }
2111 }
2112 //var_dump('indexofgroupbyold='.$indexofgroupbyold);
2113 }
2114
2115 //var_dump("tmpcursor=".$tmpcursor." groupbyold=".$groupbyold." groupbyvalue=".$groupbyvalue);
2116 if ($tmpcursor <= $indexofgroupbyvalue) {
2117 continue;
2118 }
2119 // We found a possible column with no value, we output the empty column
2120 print '<!-- empty column after column of fetched value --><div class="box-flex-container-column kanban column';
2121 if (array_key_exists($tmpcursor, $groupofcollpasedvalues)) {
2122 print ' kanbancollapsed';
2123 }
2124 print '" data-groupbyid="'.preg_replace('/[^a-z0-9]/', '', $tmpgroupbyvalue['id']).'" data-groupbyfield="'.$groupbyfield.'">';
2125 print '<div class="kanbanlabel">'.$langs->trans(empty($tmpgroupbyvalue['label']) ? 'Undefined' : $tmpgroupbyvalue['label']).'</div>';
2126 print '</div>'; // Start and end the new column
2127 }
2128 print '</div>'; // end box-flex-container-columns
2129 } else {
2130 print '</div>'; // end box-flex-container
2131 }
2132
2133 print '</td></tr>';
2134 }
2135 } else {
2136 // Author
2137 $userstatic->id = $obj->fk_user_creat;
2138 $userstatic->login = $obj->login;
2139 $userstatic->lastname = $obj->lastname;
2140 $userstatic->firstname = $obj->firstname;
2141 $userstatic->email = $obj->user_email;
2142 $userstatic->status = $obj->user_statut;
2143 $userstatic->entity = $obj->entity;
2144 $userstatic->photo = $obj->photo;
2145 $userstatic->office_phone = $obj->office_phone;
2146 $userstatic->office_fax = $obj->office_fax;
2147 $userstatic->user_mobile = $obj->user_mobile;
2148 $userstatic->job = $obj->job;
2149 $userstatic->gender = $obj->gender;
2150
2151 // Show here line of result
2152 $j = 0;
2153 print '<tr data-rowid="'.$object->id.'" class="oddeven row-with-select '.((getDolGlobalInt('MAIN_FINISHED_LINES_OPACITY') == 1 && $object->status > 1) ? 'opacitymedium' : '').'">';
2154 // Action column
2155 if ($conf->main_checkbox_left_column) {
2156 print '<td class="nowrap center">';
2157 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2158 $selected = 0;
2159 if (in_array($object->id, $arrayofselected)) {
2160 $selected = 1;
2161 }
2162 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
2163 }
2164 print '</td>';
2165 if (!$i) {
2166 $totalarray['nbfield']++;
2167 }
2168 }
2169 // Project ID
2170 if (!empty($arrayfields['p.rowid']['checked'])) {
2171 print '<td class="nowraponall">';
2172 print $object->id;
2173 print '</td>';
2174 if (!$i) {
2175 $totalarray['nbfield']++;
2176 }
2177 }
2178 // Project ref url
2179 if (!empty($arrayfields['p.ref']['checked'])) {
2180 print '<td class="nowraponall tdoverflowmax200">';
2181 print $object->getNomUrl(1, (!empty(GETPOSTINT('search_usage_event_organization')) ? 'eventorganization' : ''), 0, '', ' - ', 0, -1, '', '', 1);
2182 if ($object->hasDelay()) {
2183 print img_warning($langs->trans('Late'));
2184 }
2185 print '</td>';
2186 if (!$i) {
2187 $totalarray['nbfield']++;
2188 }
2189 }
2190 // Project title
2191 if (!empty($arrayfields['p.title']['checked'])) {
2192 print '<td class="" title="'.dolPrintHTMLForAttribute($obj->title).'">';
2193 print '<div class="twolinesmax-normallineheight minwidth200onall">';
2194 print '<span class="spantitle">';
2195 print dolPrintHTML($obj->title);
2196 print '</span>';
2197 print '</div>';
2198 print '</td>';
2199 if (!$i) {
2200 $totalarray['nbfield']++;
2201 }
2202 }
2203 // Parent Project
2204 if (!empty($arrayfields['p.fk_project']['checked'])) {
2205 print '<td class="nowraponall">';
2206 if ($object->fk_project) {
2207 $parent_object = new Project($db);
2208 $parent_result = $parent_object->fetch($object->fk_project);
2209 if ($parent_result > 0) {
2210 $accessallowed = checkUserAccessToObject($user, array('projet'), $parent_object, 'projet&project', '', '', 'rowid', '');
2211 if ($accessallowed) {
2212 print $parent_object->getNomUrl(-1);
2213 } else {
2214 $parent_url = DOL_URL_ROOT.'/projet/card.php?id='.$object->fk_project;
2215 print '<a href="'.$parent_url.'">';
2216 print img_picto('', 'warning', 'class="pictofixedwidth error"');
2217 print '<del title="You do not have access to see parent project">ACCESS DENIED!</del>';
2218 print img_picto('', 'warning', 'class="pictofixedwidth error"');
2219 print '</a>';
2220 }
2221 } else {
2222 print((int) $object->fk_project);
2223 }
2224 }
2225
2226 print '</td>';
2227 if (!$i) {
2228 $totalarray['nbfield']++;
2229 }
2230 }
2231
2232 // Company
2233 if (!empty($arrayfields['s.nom']['checked'])) {
2234 print '<td class="tdoverflowmax125">';
2235 if ($obj->socid) {
2236 print $companystatic->getNomUrl(1, '', 0, 0, -1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1);
2237 } else {
2238 print '&nbsp;';
2239 }
2240 print '</td>';
2241 if (!$i) {
2242 $totalarray['nbfield']++;
2243 }
2244 }
2245 // Alias
2246 if (!empty($arrayfields['s.name_alias']['checked'])) {
2247 print '<td class="tdoverflowmax100">';
2248 if ($obj->socid) {
2249 print '<span class="spantitle">';
2250 print $companystatic->name_alias;
2251 print '</span>';
2252 }
2253 print '</td>';
2254 if (!$i) {
2255 $totalarray['nbfield']++;
2256 }
2257 }
2258 // Ref customer
2259 if (!empty($arrayfields['s.code_client']['checked'])) {
2260 print '<td class="tdoverflowmax100">';
2261 if ($obj->socid) {
2262 print $companystatic->code_client;
2263 }
2264 print '</td>';
2265 if (!$i) {
2266 $totalarray['nbfield']++;
2267 }
2268 }
2269 // Ref supplier
2270 if (!empty($arrayfields['s.code_fournisseur']['checked'])) {
2271 print '<td class="tdoverflowmax100">';
2272 if ($obj->socid) {
2273 print $companystatic->code_fournisseur;
2274 }
2275 print '</td>';
2276 if (!$i) {
2277 $totalarray['nbfield']++;
2278 }
2279 }
2280 // Country code
2281 if (!empty($arrayfields['co.country_code']['checked'])) {
2282 print '<td class="tdoverflowmax125 center">';
2283 print $obj->country_code;
2284 print '</td>';
2285 if (!$i) {
2286 $totalarray['nbfield']++;
2287 }
2288 }
2289 // Sales Representatives
2290 if (!empty($arrayfields['commercial']['checked'])) {
2291 print '<td class="tdoverflowmax150">';
2292 if ($obj->socid) {
2293 $PROJECT_MAX_SALES_TO_SHOW_IN_LIST = getDolGlobalInt('PROJECT_MAX_SALES_TO_SHOW_IN_LIST', 5);
2294 $companystatic->id = $obj->socid;
2295 $companystatic->name = $obj->name;
2296 $listsalesrepresentatives = $companystatic->getSalesRepresentatives($user);
2297 $nbofsalesrepresentative = count($listsalesrepresentatives);
2298 if ($nbofsalesrepresentative > $PROJECT_MAX_SALES_TO_SHOW_IN_LIST) {
2299 // We print only number
2300 print $nbofsalesrepresentative;
2301 } elseif ($nbofsalesrepresentative > 0) {
2302 $userstatic = new User($db);
2303 $j = 0;
2304 foreach ($listsalesrepresentatives as $val) {
2305 $userstatic->id = $val['id'];
2306 $userstatic->lastname = $val['lastname'];
2307 $userstatic->firstname = $val['firstname'];
2308 $userstatic->email = $val['email'];
2309 $userstatic->status = $val['statut'];
2310 $userstatic->entity = $val['entity'];
2311 $userstatic->photo = $val['photo'];
2312 $userstatic->login = $val['login'];
2313 $userstatic->office_phone = $val['office_phone'];
2314 $userstatic->office_fax = $val['office_fax'];
2315 $userstatic->user_mobile = $val['user_mobile'];
2316 $userstatic->job = $val['job'];
2317 $userstatic->gender = $val['gender'];
2318 print ($nbofsalesrepresentative < 2) ? $userstatic->getNomUrl(-1, '', 0, 0, 12) : $userstatic->getNomUrl(-2);
2319 $j++;
2320 if ($j < $nbofsalesrepresentative) {
2321 print ' ';
2322 }
2323 }
2324 }
2325 //else print $langs->trans("NoSalesRepresentativeAffected");
2326 } else {
2327 print '&nbsp;';
2328 }
2329 print '</td>';
2330 if (!$i) {
2331 $totalarray['nbfield']++;
2332 }
2333 }
2334
2335 // Date start project
2336 if (!empty($arrayfields['p.dateo']['checked'])) {
2337 print '<td class="center">';
2338 print dol_print_date($db->jdate($obj->date_start), 'day');
2339 print '</td>';
2340 if (!$i) {
2341 $totalarray['nbfield']++;
2342 }
2343 }
2344 // Date end project
2345 if (!empty($arrayfields['p.datee']['checked'])) {
2346 print '<td class="center">';
2347 print dol_print_date($db->jdate($obj->date_end), 'day');
2348 print '</td>';
2349 if (!$i) {
2350 $totalarray['nbfield']++;
2351 }
2352 }
2353
2354 // Visibility
2355 if (!empty($arrayfields['p.public']['checked'])) {
2356 print '<td class="center">';
2357 if ($obj->public) {
2358 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
2359 //print $langs->trans('SharedProject');
2360 } else {
2361 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
2362 //print $langs->trans('PrivateProject');
2363 }
2364 print '</td>';
2365 if (!$i) {
2366 $totalarray['nbfield']++;
2367 }
2368 }
2369 // Assigned contacts of project
2370 if (!empty($arrayfields['c.assigned']['checked'])) {
2371 print '<td class="center nowraponall tdoverflowmax150">';
2372 print $stringassignedusers;
2373 print '</td>';
2374 if (!$i) {
2375 $totalarray['nbfield']++;
2376 }
2377 }
2378 // Opp Status
2379 if (!empty($arrayfields['p.fk_opp_status']['checked'])) {
2380 $s = '';
2381 if ($obj->opp_status_code) {
2382 $s = $langs->trans("OppStatus".$obj->opp_status_code);
2383 if (empty($arrayfields['p.opp_percent']['checked']) && $obj->opp_percent) {
2384 $s .= ' ('.dol_escape_htmltag(price2num($obj->opp_percent, 1)).'%)';
2385 }
2386 }
2387 print '<td class="center tdoverflowmax150" title="'.dolPrintHTMLForAttribute($s).'">';
2388 if ($s) {
2389 print '<span class="badge badge-oppstatus">';
2390 print dolPrintHTML($s);
2391 print '</span>';
2392 }
2393 print '</td>';
2394 if (!$i) {
2395 $totalarray['nbfield']++;
2396 }
2397 }
2398 // Opp Amount
2399 if (!empty($arrayfields['p.opp_amount']['checked'])) {
2400 print '<td class="right">';
2401 //if ($obj->opp_status_code)
2402 if (isset($obj->opp_amount) && strcmp($obj->opp_amount, '')) {
2403 print '<span class="amount">'.price($obj->opp_amount, 1, $langs, 1, -1, -1, '').'</span>';
2404 if (!isset($totalarray['val']['p.opp_amount'])) {
2405 $totalarray['val']['p.opp_amount'] = $obj->opp_amount;
2406 } else {
2407 $totalarray['val']['p.opp_amount'] += $obj->opp_amount;
2408 }
2409 }
2410 print '</td>';
2411 if (!$i) {
2412 $totalarray['nbfield']++;
2413 }
2414 if (!$i) {
2415 $totalarray['pos'][$totalarray['nbfield']] = 'p.opp_amount';
2416 }
2417 }
2418 // Opp percent
2419 if (!empty($arrayfields['p.opp_percent']['checked'])) {
2420 print '<td class="right">';
2421 if ($obj->opp_percent) {
2422 print price($obj->opp_percent, 1, $langs, 1, 0).'%';
2423 }
2424 print '</td>';
2425 if (!$i) {
2426 $totalarray['nbfield']++;
2427 }
2428 }
2429 // Opp weighted amount
2430 if (!empty($arrayfields['opp_weighted_amount']['checked'])) {
2431 if (!isset($totalarray['val']['opp_weighted_amount'])) {
2432 $totalarray['val']['opp_weighted_amount'] = 0;
2433 }
2434 print '<td align="right">';
2435 if ($obj->opp_weighted_amount) {
2436 print '<span class="amount">'.price($obj->opp_weighted_amount, 1, $langs, 1, -1, -1, '').'</span>';
2437 $totalarray['val']['opp_weighted_amount'] += $obj->opp_weighted_amount;
2438 }
2439 print '</td>';
2440 if (!$i) {
2441 $totalarray['nbfield']++;
2442 $totalarray['pos'][$totalarray['nbfield']] = 'opp_weighted_amount';
2443 }
2444 }
2445 // Budget
2446 if (!empty($arrayfields['p.budget_amount']['checked'])) {
2447 print '<td class="right">';
2448 if ($obj->budget_amount != '') {
2449 print '<span class="amount">'.price($obj->budget_amount, 1, $langs, 1, -1, -1).'</span>';
2450 if (!isset($totalarray['val']['p.budget_amount'])) {
2451 $totalarray['val']['p.budget_amount'] = $obj->budget_amount;
2452 } else {
2453 $totalarray['val']['p.budget_amount'] += $obj->budget_amount;
2454 }
2455 }
2456 print '</td>';
2457 if (!$i) {
2458 $totalarray['nbfield']++;
2459 $totalarray['pos'][$totalarray['nbfield']] = 'p.budget_amount';
2460 }
2461 }
2462 // Usage opportunity
2463 if (!empty($arrayfields['p.usage_opportunity']['checked'])) {
2464 print '<td class="center">';
2465 if ($obj->usage_opportunity) {
2466 print yn($obj->usage_opportunity, 4);
2467 }
2468 print '</td>';
2469 if (!$i) {
2470 $totalarray['nbfield']++;
2471 }
2472 }
2473 // Usage task
2474 if (!empty($arrayfields['p.usage_task']['checked'])) {
2475 print '<td class="center">';
2476 if ($obj->usage_task) {
2477 print yn($obj->usage_task, 4);
2478 }
2479 print '</td>';
2480 if (!$i) {
2481 $totalarray['nbfield']++;
2482 }
2483 }
2484 // Usage bill time
2485 if (!empty($arrayfields['p.usage_bill_time']['checked'])) {
2486 print '<td class="center">';
2487 if ($obj->usage_bill_time) {
2488 print yn($obj->usage_bill_time, 4);
2489 }
2490 print '</td>';
2491 if (!$i) {
2492 $totalarray['nbfield']++;
2493 }
2494 }
2495 // Usage event organization
2496 if (!empty($arrayfields['p.usage_organize_event']['checked'])) {
2497 print '<td class="center">';
2498 if ($obj->usage_organize_event) {
2499 print yn($obj->usage_organize_event, 4);
2500 }
2501 print '</td>';
2502 if (!$i) {
2503 $totalarray['nbfield']++;
2504 }
2505 }
2506 // Allow unknown people to suggest conferences
2507 if (!empty($arrayfields['p.accept_conference_suggestions']['checked'])) {
2508 print '<td class="center">';
2509 if ($obj->accept_conference_suggestions) {
2510 print yn($obj->accept_conference_suggestions);
2511 }
2512 print '</td>';
2513 if (!$i) {
2514 $totalarray['nbfield']++;
2515 }
2516 }
2517 // Allow unknown people to suggest booth
2518 if (!empty($arrayfields['p.accept_booth_suggestions']['checked'])) {
2519 print '<td class="">';
2520 if ($obj->accept_booth_suggestions) {
2521 print yn($obj->accept_booth_suggestions);
2522 }
2523 print '</td>';
2524 if (!$i) {
2525 $totalarray['nbfield']++;
2526 }
2527 }
2528 // Price of registration
2529 if (!empty($arrayfields['p.price_registration']['checked'])) {
2530 print '<td class="right">';
2531 if ($obj->price_registration != '') {
2532 print '<span class="amount">'.price($obj->price_registration, 1, $langs, 1, -1, -1).'</span>';
2533 $totalarray['val']['p.price_registration'] += $obj->price_registration;
2534 }
2535 print '</td>';
2536 if (!$i) {
2537 $totalarray['nbfield']++;
2538 }
2539 if (!$i) {
2540 $totalarray['pos'][$totalarray['nbfield']] = 'p.price_registration';
2541 }
2542 }
2543 // Price of booth
2544 if (!empty($arrayfields['p.price_booth']['checked'])) {
2545 print '<td class="right">';
2546 if ($obj->price_booth != '') {
2547 print '<span class="amount">'.price($obj->price_booth, 1, $langs, 1, -1, -1).'</span>';
2548 $totalarray['val']['p.price_booth'] += $obj->price_booth;
2549 }
2550 print '</td>';
2551 if (!$i) {
2552 $totalarray['nbfield']++;
2553 }
2554 if (!$i) {
2555 $totalarray['pos'][$totalarray['nbfield']] = 'p.price_booth';
2556 }
2557 }
2558 // Author
2559 if (!empty($arrayfields['u.login']['checked'])) {
2560 print '<td class="center tdoverflowmax150">';
2561 if ($userstatic->id) {
2562 print $userstatic->getNomUrl(-1);
2563 }
2564 print "</td>\n";
2565 if (!$i) {
2566 $totalarray['nbfield']++;
2567 }
2568 }
2569 // Note public
2570 if (!empty($arrayfields['p.note_public']['checked'])) {
2571 print '<td class="flat maxwidth250imp">';
2572 print '<div class="small lineheightsmall twolinesmax-normallineheight">'.dolPrintHTML(dolGetFirstLineOfText($obj->note_public, 5)).'</div>';
2573 print '</td>';
2574 if (!$i) {
2575 $totalarray['nbfield']++;
2576 }
2577 }
2578 // Note private
2579 if (!empty($arrayfields['p.note_private']['checked'])) {
2580 print '<td class="flat maxwidth250imp">';
2581 print '<div class="small lineheightsmall twolinesmax-normallineheight">'.dolPrintHTML(dolGetFirstLineOfText($obj->note_private, 5)).'</div>';
2582 print '</td>';
2583 if (!$i) {
2584 $totalarray['nbfield']++;
2585 }
2586 }
2587 // Extra fields
2588 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2589 // Fields from hook
2590 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
2591 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2592 print $hookmanager->resPrint;
2593 // Date creation
2594 if (!empty($arrayfields['p.datec']['checked'])) {
2595 print '<td class="center nowraponall">';
2596 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
2597 print '</td>';
2598 if (!$i) {
2599 $totalarray['nbfield']++;
2600 }
2601 }
2602 // Date modification
2603 if (!empty($arrayfields['p.tms']['checked'])) {
2604 print '<td class="center nowraponall">';
2605 print dol_print_date($db->jdate($obj->date_modification), 'dayhour', 'tzuser');
2606 print '</td>';
2607 if (!$i) {
2608 $totalarray['nbfield']++;
2609 }
2610 }
2611 // Email MsgID
2612 if (!empty($arrayfields['p.email_msgid']['checked'])) {
2613 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($obj->email_msgid).'">';
2614 print dol_escape_htmltag($obj->email_msgid);
2615 print '</td>';
2616 if (!$i) {
2617 $totalarray['nbfield']++;
2618 }
2619 }
2620 // Import key
2621 if (!empty($arrayfields['p.import_key']['checked'])) {
2622 print '<td class="right">'.dol_escape_htmltag($obj->import_key).'</td>';
2623 if (!$i) {
2624 $totalarray['nbfield']++;
2625 }
2626 }
2627 // Status
2628 if (!empty($arrayfields['p.fk_statut']['checked'])) {
2629 print '<td class="center">'.$object->getLibStatut(5).'</td>';
2630 if (!$i) {
2631 $totalarray['nbfield']++;
2632 }
2633 }
2634 // Action column
2635 if (!$conf->main_checkbox_left_column) {
2636 print '<td class="nowrap center">';
2637 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2638 $selected = 0;
2639 if (in_array($object->id, $arrayofselected)) {
2640 $selected = 1;
2641 }
2642 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
2643 }
2644 print '</td>';
2645 if (!$i) {
2646 $totalarray['nbfield']++;
2647 }
2648 }
2649
2650 print '</tr>'."\n";
2651 }
2652
2653 $i++;
2654}
2655
2656// Show total line
2657include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
2658
2659// If no record found
2660if ($num == 0) {
2661 $colspan = 1;
2662 foreach ($arrayfields as $key => $val) {
2663 if (!empty($val['checked'])) {
2664 $colspan++;
2665 }
2666 }
2667 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
2668}
2669
2670$db->free($resql);
2671
2672$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
2673$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2674print $hookmanager->resPrint;
2675
2676print '</table>'."\n";
2677print '</div>'."\n";
2678
2679print '</form>'."\n";
2680
2681if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
2682 $hidegeneratedfilelistifempty = 1;
2683 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
2684 $hidegeneratedfilelistifempty = 0;
2685 }
2686
2687 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
2688 $formfile = new FormFile($db);
2689
2690 // Show list of available documents
2691 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
2692 $urlsource .= str_replace('&amp;', '&', $param);
2693
2694 $filedir = $diroutputmassaction;
2695 $genallowed = $permissiontoread;
2696 $delallowed = $permissiontoadd;
2697
2698 print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
2699}
2700
2701// End of page
2702llxFooter();
2703$db->close();
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
$c
Definition line.php:346
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 to help generate other html components 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:391
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
GETPOSTDATE($prefix, $hourTime='', $gm='auto', $saverestore='')
Helper function that combines values of a dolibarr DatePicker (such as Form\selectDate) for year,...
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
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.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
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.
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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
checkUserAccessToObject($user, array $featuresarray, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid', $parenttableforentity='')
Check that access by a given user to an object is ok.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.