1<?php
2/* Copyright (C) 2001-2004	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2020	Laurent Destailleur		<eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2017	Regis Houssin			<regis.houssin@inodbox.com>
5 * Copyright (C) 2011-2012	Juanjo Menent			<jmenent@2byte.es>
6 * Copyright (C) 2015		Marcos García			<marcosgdf@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22/**
23 *	\file       htdocs/index.php
24 *	\brief      Dolibarr home page
25 */
26
27define('NOCSRFCHECK', 1); // This is main home and login page. We must be able to go on it from another web site.
28
29require 'main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
31
32// If not defined, we select menu "home"
33$_GET['mainmenu'] = GETPOST('mainmenu', 'aZ09') ?GETPOST('mainmenu', 'aZ09') : 'home';
34$action = GETPOST('action', 'aZ09');
35
36$hookmanager->initHooks(array('index'));
37
38
39/*
40 * Actions
41 */
42
43// Check if company name is defined (first install)
44if (!isset($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_NOM))
45{
46	header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
47	exit;
48}
49if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING))	// If only user module enabled
50{
51	header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
52	exit;
53}
54if (GETPOST('addbox'))	// Add box (when submit is done from a form when ajax disabled)
55{
56	require_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php';
57	$zone = GETPOST('areacode', 'aZ09');
58	$userid = GETPOST('userid', 'int');
59	$boxorder = GETPOST('boxorder', 'aZ09');
60	$boxorder .= GETPOST('boxcombo', 'aZ09');
61
62	$result = InfoBox::saveboxorder($db, $zone, $boxorder, $userid);
63	if ($result > 0) setEventMessages($langs->trans("BoxAdded"), null);
64}
65
66
67/*
68 * View
69 */
70
71if (!isset($form) || !is_object($form)) $form = new Form($db);
72
73// Title
74$title = $langs->trans("HomeArea").' - Dolibarr '.DOL_VERSION;
75if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $title = $langs->trans("HomeArea").' - '.$conf->global->MAIN_APPLICATION_TITLE;
76
77llxHeader('', $title);
78
79
80$resultboxes = FormOther::getBoxesArea($user, "0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb)
81
82
83print load_fiche_titre('&nbsp;', $resultboxes['selectboxlist'], '', 0, '', 'titleforhome');
84
85if (!empty($conf->global->MAIN_MOTD))
86{
87	$conf->global->MAIN_MOTD = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>/i', '<br>', $conf->global->MAIN_MOTD);
88	if (!empty($conf->global->MAIN_MOTD))
89	{
90		$substitutionarray = getCommonSubstitutionArray($langs);
91		complete_substitutions_array($substitutionarray, $langs);
92		$texttoshow = make_substitutions($conf->global->MAIN_MOTD, $substitutionarray, $langs);
93
94		print "\n<!-- Start of welcome text -->\n";
95		print '<table width="100%" class="notopnoleftnoright"><tr><td>';
96		print dol_htmlentitiesbr($texttoshow);
97		print '</td></tr></table><br>';
98		print "\n<!-- End of welcome text -->\n";
99	}
100}
101
102
103
104/*
105 * Dashboard Dolibarr states (statistics)
106 * Hidden for external users
107 */
108
109$boxstatItems = array();
110$boxstatFromHook = '';
111
112// Load translation files required by page
113$langs->loadLangs(array('commercial', 'bills', 'orders', 'contracts'));
114
115// Load global statistics of objects
116if (empty($user->socid) && empty($conf->global->MAIN_DISABLE_GLOBAL_BOXSTATS))
117{
118	$object = new stdClass();
119	$parameters = array();
120	$action = '';
121	$reshook = $hookmanager->executeHooks('addStatisticLine', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
122	$boxstatFromHook = $hookmanager->resPrint;
123
124	if (empty($reshook))
125	{
126		// Cle array returned by the method load_state_board for each line
127		$keys = array(
128			'users',
129			'members',
130			'expensereports',
131			'holidays',
132			'customers',
133			'prospects',
134			'suppliers',
135			'contacts',
136			'products',
137			'services',
138			'projects',
139			'proposals',
140			'orders',
141			'invoices',
142			'donations',
143			'supplier_proposals',
144			'supplier_orders',
145			'supplier_invoices',
146			'contracts',
147			'interventions',
148			'ticket'
149		);
150
151		// Condition to be checked for each display line dashboard
152		$conditions = array(
153			'users' => $user->rights->user->user->lire,
154			'members' => !empty($conf->adherent->enabled) && $user->rights->adherent->lire,
155			'customers' => !empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS),
156			'prospects' => !empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS),
157			'suppliers' => !empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS),
158			'contacts' => !empty($conf->societe->enabled) && $user->rights->societe->contact->lire,
159			'products' => !empty($conf->product->enabled) && $user->rights->produit->lire,
160			'services' => !empty($conf->service->enabled) && $user->rights->service->lire,
161			'proposals' => !empty($conf->propal->enabled) && $user->rights->propale->lire,
162			'orders' => !empty($conf->commande->enabled) && $user->rights->commande->lire,
163			'invoices' => !empty($conf->facture->enabled) && $user->rights->facture->lire,
164			'donations' => !empty($conf->don->enabled) && $user->rights->don->lire,
165			'contracts' => !empty($conf->contrat->enabled) && $user->rights->contrat->lire,
166			'interventions' => !empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire,
167			'supplier_orders' => !empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS),
168			'supplier_invoices' => !empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS),
169			'supplier_proposals' => !empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS),
170			'projects' => !empty($conf->projet->enabled) && $user->rights->projet->lire,
171			'expensereports' => !empty($conf->expensereport->enabled) && $user->rights->expensereport->lire,
172			'holidays' => !empty($conf->holiday->enabled) && $user->rights->holiday->read,
173			'ticket' => !empty($conf->ticket->enabled) && $user->rights->ticket->read
174		);
175		// Class file containing the method load_state_board for each line
176		$includes = array(
177			'users' => DOL_DOCUMENT_ROOT."/user/class/user.class.php",
178			'members' => DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php",
179			'customers' => DOL_DOCUMENT_ROOT."/societe/class/client.class.php",
180			'prospects' => DOL_DOCUMENT_ROOT."/societe/class/client.class.php",
181			'suppliers' => DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.class.php",
182			'contacts' => DOL_DOCUMENT_ROOT."/contact/class/contact.class.php",
183			'products' => DOL_DOCUMENT_ROOT."/product/class/product.class.php",
184			'services' => DOL_DOCUMENT_ROOT."/product/class/product.class.php",
185			'proposals' => DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php",
186			'orders' => DOL_DOCUMENT_ROOT."/commande/class/commande.class.php",
187			'invoices' => DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php",
188			'donations' => DOL_DOCUMENT_ROOT."/don/class/don.class.php",
189			'contracts' => DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php",
190			'interventions' => DOL_DOCUMENT_ROOT."/fichinter/class/fichinter.class.php",
191			'supplier_orders' => DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.commande.class.php",
192			'supplier_invoices' => DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php",
193			'supplier_proposals' => DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php",
194			'projects' => DOL_DOCUMENT_ROOT."/projet/class/project.class.php",
195			'expensereports' => DOL_DOCUMENT_ROOT."/expensereport/class/expensereport.class.php",
196			'holidays' => DOL_DOCUMENT_ROOT."/holiday/class/holiday.class.php",
197			'ticket' => DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php"
198		);
199		// Name class containing the method load_state_board for each line
200		$classes = array(
201			'users' => 'User',
202			'members' => 'Adherent',
203			'customers' => 'Client',
204			'prospects' => 'Client',
205			'suppliers' => 'Fournisseur',
206			'contacts' => 'Contact',
207			'products' => 'Product',
208			'services' => 'ProductService',
209			'proposals' => 'Propal',
210			'orders' => 'Commande',
211			'invoices' => 'Facture',
212			'donations' => 'Don',
213			'contracts' => 'Contrat',
214			'interventions' => 'Fichinter',
215			'supplier_orders' => 'CommandeFournisseur',
216			'supplier_invoices' => 'FactureFournisseur',
217			'supplier_proposals' => 'SupplierProposal',
218			'projects' => 'Project',
219			'expensereports' => 'ExpenseReport',
220			'holidays' => 'Holiday',
221			'ticket' => 'Ticket',
222		);
223		// Translation keyword
224		$titres = array(
225			'users' => "Users",
226			'members' => "Members",
227			'customers' => "ThirdPartyCustomersStats",
228			'prospects' => "ThirdPartyProspectsStats",
229			'suppliers' => "Suppliers",
230			'contacts' => "Contacts",
231			'products' => "Products",
232			'services' => "Services",
233			'proposals' => "CommercialProposalsShort",
234			'orders' => "CustomersOrders",
235			'invoices' => "BillsCustomers",
236			'donations' => "Donations",
237			'contracts' => "Contracts",
238			'interventions' => "Interventions",
239			'supplier_orders' => "SuppliersOrders",
240			'supplier_invoices' => "SuppliersInvoices",
241			'supplier_proposals' => "SupplierProposalShort",
242			'projects' => "Projects",
243			'expensereports' => "ExpenseReports",
244			'holidays' => "Holidays",
245			'ticket' => "Ticket",
246		);
247		// Dashboard Link lines
248		$links = array(
249			'users' => DOL_URL_ROOT.'/user/list.php',
250			'members' => DOL_URL_ROOT.'/adherents/list.php?statut=1&mainmenu=members',
251			'customers' => DOL_URL_ROOT.'/societe/list.php?type=c&mainmenu=companies',
252			'prospects' => DOL_URL_ROOT.'/societe/list.php?type=p&mainmenu=companies',
253			'suppliers' => DOL_URL_ROOT.'/societe/list.php?type=f&mainmenu=companies',
254			'contacts' => DOL_URL_ROOT.'/contact/list.php?mainmenu=companies',
255			'products' => DOL_URL_ROOT.'/product/list.php?type=0&mainmenu=products',
256			'services' => DOL_URL_ROOT.'/product/list.php?type=1&mainmenu=products',
257			'proposals' => DOL_URL_ROOT.'/comm/propal/list.php?mainmenu=commercial&leftmenu=propals',
258			'orders' => DOL_URL_ROOT.'/commande/list.php?mainmenu=commercial&leftmenu=orders',
259			'invoices' => DOL_URL_ROOT.'/compta/facture/list.php?mainmenu=billing&leftmenu=customers_bills',
260			'donations' => DOL_URL_ROOT.'/don/list.php?leftmenu=donations',
261			'contracts' => DOL_URL_ROOT.'/contrat/list.php?mainmenu=commercial&leftmenu=contracts',
262			'interventions' => DOL_URL_ROOT.'/fichinter/list.php?mainmenu=commercial&leftmenu=ficheinter',
263			'supplier_orders' => DOL_URL_ROOT.'/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers',
264			'supplier_invoices' => DOL_URL_ROOT.'/fourn/facture/list.php?mainmenu=billing&leftmenu=suppliers_bills',
265			'supplier_proposals' => DOL_URL_ROOT.'/supplier_proposal/list.php?mainmenu=commercial&leftmenu=',
266			'projects' => DOL_URL_ROOT.'/projet/list.php?mainmenu=project',
267			'expensereports' => DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm&leftmenu=expensereport',
268			'holidays' => DOL_URL_ROOT.'/holiday/list.php?mainmenu=hrm&leftmenu=holiday',
269			'ticket' => DOL_URL_ROOT.'/ticket/list.php?leftmenu=ticket'
270		);
271		// Translation lang files
272		$langfile = array(
273			'customers' => "companies",
274			'contacts' => "companies",
275			'services' => "products",
276			'proposals' => "propal",
277			'invoices' => "bills",
278			'supplier_orders' => "orders",
279			'supplier_invoices' => "bills",
280			'supplier_proposals' => 'supplier_proposal',
281			'expensereports' => "trips",
282			'holidays' => "holiday",
283		);
284
285
286		// Loop and displays each line of table
287		$boardloaded = array();
288		foreach ($keys as $val)
289		{
290			if ($conditions[$val])
291			{
292				$boxstatItem = '';
293				$class = $classes[$val];
294				// Search in cache if load_state_board is already realized
295				$classkeyforcache = $class;
296				if ($classkeyforcache == 'ProductService') $classkeyforcache = 'Product'; // ProductService use same load_state_board than Product
297
298				if (!isset($boardloaded[$classkeyforcache]) || !is_object($boardloaded[$classkeyforcache]))
299				{
300					include_once $includes[$val]; // Loading a class cost around 1Mb
301
302					$board = new $class($db);
303					$board->load_state_board();
304					$boardloaded[$class] = $board;
305				} else {
306					$board = $boardloaded[$classkeyforcache];
307				}
308
309				$langs->load(empty($langfile[$val]) ? $val : $langfile[$val]);
310
311				$text = $langs->trans($titres[$val]);
312				$boxstatItem .= '<a href="'.$links[$val].'" class="boxstatsindicator thumbstat nobold nounderline">';
313				$boxstatItem .= '<div class="boxstats">';
314				$boxstatItem .= '<span class="boxstatstext" title="'.dol_escape_htmltag($text).'">'.$text.'</span><br>';
315				$boxstatItem .= '<span class="boxstatsindicator">'.img_object("", $board->picto, 'class="inline-block"').' '.($board->nb[$val] ? $board->nb[$val] : 0).'</span>';
316				$boxstatItem .= '</div>';
317				$boxstatItem .= '</a>';
318
319				$boxstatItems[$val] = $boxstatItem;
320			}
321		}
322	}
323}
324
325
326
327
328// Dolibarr Working Board with weather
329
330if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) {
331	$showweather = (empty($conf->global->MAIN_DISABLE_METEO) || $conf->global->MAIN_DISABLE_METEO == 2) ? 1 : 0;
332
333	//Array that contains all WorkboardResponse classes to process them
334	$dashboardlines = array();
335
336	// Do not include sections without management permission
337	require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
338
339	// Number of actions to do (late)
340	if (!empty($conf->agenda->enabled) && $user->rights->agenda->myactions->read) {
341		include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
342		$board = new ActionComm($db);
343		$dashboardlines[$board->element] = $board->load_board($user);
344	}
345
346	// Number of project opened
347	if (!empty($conf->projet->enabled) && $user->rights->projet->lire) {
348		include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
349		$board = new Project($db);
350		$dashboardlines[$board->element] = $board->load_board($user);
351	}
352
353	// Number of tasks to do (late)
354	if (!empty($conf->projet->enabled) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->rights->projet->lire) {
355		include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
356		$board = new Task($db);
357		$dashboardlines[$board->element] = $board->load_board($user);
358	}
359
360	// Number of commercial proposals open (expired)
361	if (!empty($conf->propal->enabled) && $user->rights->propale->lire) {
362		include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
363		$board = new Propal($db);
364		$dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
365		// Number of commercial proposals CLOSED signed (billed)
366		$dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
367	}
368
369	// Number of commercial proposals open (expired)
370	if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) {
371		include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
372		$board = new SupplierProposal($db);
373		$dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
374		// Number of commercial proposals CLOSED signed (billed)
375		$dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
376	}
377
378	// Number of customer orders a deal
379	if (!empty($conf->commande->enabled) && $user->rights->commande->lire) {
380		include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
381		$board = new Commande($db);
382		$dashboardlines[$board->element] = $board->load_board($user);
383	}
384
385	// Number of suppliers orders a deal
386	if (!empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire) {
387		include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
388		$board = new CommandeFournisseur($db);
389		$dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
390		$dashboardlines[$board->element.'_awaiting'] = $board->load_board($user, 'awaiting');
391	}
392
393	// Number of contract / services enabled (delayed)
394	if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) {
395		include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
396		$board = new Contrat($db);
397		$dashboardlines[$board->element.'_inactive'] = $board->load_board($user, "inactive");
398		// Number of active services (expired)
399		$dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
400	}
401
402	// Number of tickets open
403	if (!empty($conf->ticket->enabled) && $user->rights->ticket->read) {
404		include_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
405		$board = new Ticket($db);
406		$dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
407		// Number of active services (expired)
408		//$dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
409	}
410
411	// Number of invoices customers (paid)
412	if (!empty($conf->facture->enabled) && $user->rights->facture->lire) {
413		include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
414		$board = new Facture($db);
415		$dashboardlines[$board->element] = $board->load_board($user);
416	}
417
418	// Number of supplier invoices (paid)
419	if (!empty($conf->supplier_invoice->enabled) && !empty($user->rights->fournisseur->facture->lire)) {
420		include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
421		$board = new FactureFournisseur($db);
422		$dashboardlines[$board->element] = $board->load_board($user);
423	}
424
425	// Number of transactions to conciliate
426	if (!empty($conf->banque->enabled) && $user->rights->banque->lire && !$user->socid) {
427		include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
428		$board = new Account($db);
429		$nb = $board->countAccountToReconcile(); // Get nb of account to reconciliate
430		if ($nb > 0) {
431			$dashboardlines[$board->element] = $board->load_board($user);
432		}
433	}
434
435	// Number of cheque to send
436	if (!empty($conf->banque->enabled) && $user->rights->banque->lire && !$user->socid && empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) {
437		include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php';
438		$board = new RemiseCheque($db);
439		$dashboardlines[$board->element] = $board->load_board($user);
440	}
441
442	// Number of foundation members
443	if (!empty($conf->adherent->enabled) && $user->rights->adherent->lire && !$user->socid) {
444		include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
445		$board = new Adherent($db);
446		$dashboardlines[$board->element.'_shift'] = $board->load_board($user, 'shift');
447		$dashboardlines[$board->element.'_expired'] = $board->load_board($user, 'expired');
448	}
449
450	// Number of expense reports to approve
451	if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->approve) {
452		include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
453		$board = new ExpenseReport($db);
454		$dashboardlines[$board->element.'_toapprove'] = $board->load_board($user, 'toapprove');
455	}
456
457	// Number of expense reports to pay
458	if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->to_paid) {
459		include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
460		$board = new ExpenseReport($db);
461		$dashboardlines[$board->element.'_topay'] = $board->load_board($user, 'topay');
462	}
463
464	// Number of holidays to approve
465	if (!empty($conf->holiday->enabled) && $user->rights->holiday->approve) {
466		include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
467		$board = new Holiday($db);
468		$dashboardlines[$board->element] = $board->load_board($user);
469	}
470
471	$object = new stdClass();
472	$parameters = array();
473	$action = '';
474	$reshook = $hookmanager->executeHooks('addOpenElementsDashboardLine', $parameters, $object,
475		$action); // Note that $action and $object may have been modified by some hooks
476	if ($reshook == 0) {
477		$dashboardlines = array_merge($dashboardlines, $hookmanager->resArray);
478	}
479
480	/* Open object dashboard */
481	$dashboardgroup = array(
482		'action' =>
483			array(
484				'groupName' => 'Agenda',
485				'stats' => array('action'),
486			),
487		'project' =>
488			array(
489				'groupName' => 'Projects',
490				'globalStatsKey' => 'projects',
491				'stats' => array('project', 'project_task'),
492			),
493		'propal' =>
494			array(
495				'groupName' => 'Proposals',
496				'globalStatsKey' => 'proposals',
497				'stats' =>
498					array('propal_opened', 'propal_signed'),
499			),
500		'commande' =>
501			array(
502				'groupName' => 'Orders',
503				'globalStatsKey' => 'orders',
504				'stats' =>
505					array('commande'),
506			),
507		'facture' =>
508			array(
509				'groupName' => 'Invoices',
510				'globalStatsKey' => 'invoices',
511				'stats' =>
512					array('facture'),
513			),
514		'supplier_proposal' =>
515			array(
516				'groupName' => 'SupplierProposals',
517				'globalStatsKey' => 'askprice',
518				'stats' =>
519					array('supplier_proposal_opened', 'supplier_proposal_signed'),
520			),
521		'order_supplier' =>
522			array(
523				'groupName' => 'SuppliersOrders',
524				'globalStatsKey' => 'supplier_orders',
525				'stats' =>
526					array('order_supplier_opened', 'order_supplier_awaiting'),
527			),
528		'invoice_supplier' =>
529			array(
530				'groupName' => 'BillsSuppliers',
531				'globalStatsKey' => 'supplier_invoices',
532				'stats' =>
533					array('invoice_supplier'),
534			),
535		'contrat' =>
536			array(
537				'groupName' => 'Contracts',
538				'globalStatsKey' => 'Contracts',
539				'stats' =>
540				array('contrat_inactive', 'contrat_active'),
541			),
542		'ticket' =>
543			array(
544				'groupName' => 'Tickets',
545				'globalStatsKey' => 'ticket',
546				'stats' =>
547					array('ticket_opened'),
548			),
549		'bank_account' =>
550			array(
551				'groupName' => 'BankAccount',
552				'stats' =>
553					array('bank_account', 'chequereceipt'),
554			),
555		'member' =>
556			array(
557				'groupName' => 'Members',
558				'globalStatsKey' => 'members',
559				'stats' =>
560					array('member_shift', 'member_expired'),
561			),
562		'expensereport' =>
563			array(
564				'groupName' => 'ExpenseReport',
565				'globalStatsKey' => 'expensereports',
566				'stats' =>
567					array('expensereport_toapprove', 'expensereport_topay'),
568			),
569		'holiday' =>
570			array(
571				'groupName' => 'Holidays',
572				'globalStatsKey' => 'holidays',
573				'stats' =>
574					array('holiday'),
575			),
576	);
577
578	$object = new stdClass();
579	$parameters = array(
580		'dashboardgroup' => $dashboardgroup
581	);
582	$reshook = $hookmanager->executeHooks('addOpenElementsDashboardGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
583	if ($reshook == 0) {
584		$dashboardgroup = array_merge($dashboardgroup, $hookmanager->resArray);
585	}
586
587
588	// Calculate total nb of late
589	$totallate = $totaltodo = 0;
590
591	//Remove any invalid response
592	//load_board can return an integer if failed or WorkboardResponse if OK
593	$valid_dashboardlines = array();
594	foreach ($dashboardlines as $workboardid => $tmp) {
595		if ($tmp instanceof WorkboardResponse) {
596			$tmp->id = $workboardid; // Complete the object to add its id into its name
597			$valid_dashboardlines[$workboardid] = $tmp;
598		}
599	}
600
601	// We calculate $totallate. Must be defined before start of next loop because it is show in first fetch on next loop
602	foreach ($valid_dashboardlines as $board) {
603		if ($board->nbtodolate > 0) {
604			$totaltodo += $board->nbtodo;
605			$totallate += $board->nbtodolate;
606		}
607	}
608
609	$openedDashBoardSize = 'info-box-sm'; // use sm by default
610	foreach ($dashboardgroup as $dashbordelement) {
611		if (is_array($dashbordelement['stats']) && count($dashbordelement['stats']) > 2) {
612			$openedDashBoardSize = ''; // use default info box size : big
613			break;
614		}
615	}
616
617	$totalLateNumber = $totallate;
618	$totallatePercentage = ((!empty($totaltodo)) ? round($totallate / $totaltodo * 100, 2) : 0);
619	if (!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) {
620		$totallate = $totallatePercentage;
621	}
622
623	$boxwork = '';
624	$boxwork .= '<div class="box">';
625	$boxwork .= '<table summary="'.dol_escape_htmltag($langs->trans("WorkingBoard")).'" class="noborder boxtable boxtablenobottom boxworkingboard" width="100%">'."\n";
626	$boxwork .= '<tr class="liste_titre">';
627	$boxwork .= '<th class="liste_titre"><div class="inline-block valignmiddle">'.$langs->trans("DolibarrWorkBoard").'</div>';
628	if ($showweather) {
629		if ($totallate > 0) {
630			$text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",
631					$totallate.(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? '%' : '')).')';
632		} else {
633			$text = $langs->transnoentitiesnoconv("NoItemLate");
634		}
635		$text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
636		//$text.=$form->textwithpicto('',$langs->trans("LateDesc"));
637		$options = 'height="24px" style="float: right"';
638		$boxwork .= showWeather($totallate, $text, $options, 'inline-block valignmiddle');
639	}
640	$boxwork .= '</th>';
641	$boxwork .= '</tr>'."\n";
642
643	// Show dashboard
644	$nbworkboardempty = 0;
645	$isIntopOpenedDashBoard = $globalStatInTopOpenedDashBoard = array();
646	if (!empty($valid_dashboardlines)) {
647		$openedDashBoard = '';
648
649		$boxwork .= '<tr class="nobottom nohover"><td class="tdboxstats nohover flexcontainer centpercent"><div style="display: flex: flex-wrap: wrap">';
650
651		foreach ($dashboardgroup as $groupKey => $groupElement) {
652			$boards = array();
653			if (empty($conf->global->MAIN_DISABLE_NEW_OPENED_DASH_BOARD)) {
654				foreach ($groupElement['stats'] as $infoKey) {
655					if (!empty($valid_dashboardlines[$infoKey])) {
656						$boards[] = $valid_dashboardlines[$infoKey];
657						$isIntopOpenedDashBoard[] = $infoKey;
658					}
659				}
660			}
661
662			if (!empty($boards)) {
663				$groupName = $langs->trans($groupElement['groupName']);
664				$groupKeyLowerCase = strtolower($groupKey);
665				$nbTotalForGroup = 0;
666
667				// global stats
668				$globalStatsKey = false;
669				if (!empty($groupElement['globalStatsKey']) && empty($groupElement['globalStats'])) { // can be filled by hook
670					$globalStatsKey = $groupElement['globalStatsKey'];
671					$groupElement['globalStats'] = array();
672
673					if (is_array($keys) && in_array($globalStatsKey, $keys))
674					{
675						// get key index of stats used in $includes, $classes, $keys, $icons, $titres, $links
676						$keyIndex = array_search($globalStatsKey, $keys);
677
678						$classe = $classes[$keyIndex];
679						if (isset($boardloaded[$classe]) && is_object($boardloaded[$classe]))
680						{
681							$groupElement['globalStats']['total'] = $boardloaded[$classe]->nb[$globalStatsKey] ? $boardloaded[$classe]->nb[$globalStatsKey] : 0;
682							$nbTotal = doubleval($groupElement['globalStats']['total']);
683							if ($nbTotal >= 10000) { $nbTotal = round($nbTotal / 1000, 2).'k'; }
684							$groupElement['globalStats']['text'] = $langs->trans('Total').' : '.$langs->trans($titres[$keyIndex]).' ('.$groupElement['globalStats']['total'].')';
685							$groupElement['globalStats']['total'] = $nbTotal;
686							$groupElement['globalStats']['link'] = $links[$keyIndex];
687						}
688					}
689				}
690
691				$openedDashBoard .= '<div class="box-flex-item"><div class="box-flex-item-with-margin">'."\n";
692				$openedDashBoard .= '	<div class="info-box '.$openedDashBoardSize.'">'."\n";
693				$openedDashBoard .= '		<span class="info-box-icon bg-infobox-'.$groupKeyLowerCase.'">'."\n";
694				$openedDashBoard .= '		<i class="fa fa-dol-'.$groupKeyLowerCase.'"></i>'."\n";
695
696				// Show the span for the total of record
697				if (!empty($groupElement['globalStats'])) {
698					$globalStatInTopOpenedDashBoard[] = $globalStatsKey;
699					$openedDashBoard .= '<span class="info-box-icon-text" title="'.$groupElement['globalStats']['text'].'">'.$nbTotal.'</span>';
700				}
701
702				$openedDashBoard .= '</span>'."\n";
703				$openedDashBoard .= '<div class="info-box-content">'."\n";
704
705				$openedDashBoard .= '<div class="info-box-title" title="'.strip_tags($groupName).'">'.$groupName.'</div>'."\n";
706				$openedDashBoard .= '<div class="info-box-lines">'."\n";
707
708				foreach ($boards as $board) {
709					$openedDashBoard .= '<div class="info-box-line">';
710
711					if (!empty($board->labelShort)) {
712						$infoName = '<span title="'.$board->label.'">'.$board->labelShort.'</span>';
713					} else {
714						$infoName = $board->label;
715					}
716
717					$textLateTitle = $langs->trans("NActionsLate", $board->nbtodolate);
718					$textLateTitle .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')';
719
720					if ($board->id == 'bank_account') {
721						$textLateTitle .= '<br><span class="opacitymedium">'.$langs->trans("IfYouDontReconcileDisableProperty", $langs->transnoentitiesnoconv("Conciliable")).'</span>';
722					}
723
724					$textLate = '';
725					if ($board->nbtodolate > 0) {
726						$textLate .= '<span title="'.dol_escape_htmltag($textLateTitle).'" class="classfortooltip badge badge-warning">';
727						$textLate .= '<i class="fa fa-exclamation-triangle"></i> '.$board->nbtodolate;
728						$textLate .= '</span>';
729					}
730
731					$nbtodClass = '';
732					if ($board->nbtodo > 0) {
733						$nbtodClass = 'badge badge-info';
734					}
735
736					$openedDashBoard .= '			<a href="'.$board->url.'" class="info-box-text info-box-text-a">'.$infoName.' : <span class="'.$nbtodClass.' classfortooltip" title="'.$board->label.'" >'.$board->nbtodo.'</span>';
737					if ($textLate) {
738						if ($board->url_late) {
739							$openedDashBoard .= '</a>';
740							$openedDashBoard .= ' <a href="'.$board->url_late.'" class="info-box-text info-box-text-a paddingleft">';
741						} else {
742							$openedDashBoard .= ' ';
743						}
744						$openedDashBoard .= $textLate;
745					}
746					$openedDashBoard .= '</a>'."\n";
747
748					if ($board->total > 0 && !empty($conf->global->MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX)) {
749						$openedDashBoard .= '<a href="'.$board->url.'" class="info-box-text">'.$langs->trans('Total').' : '.price($board->total).'</a>';
750					}
751					$openedDashBoard .= '</div>'."\n";
752				}
753
754				// TODO Add hook here to add more "info-box-line"
755
756				$openedDashBoard .= '		</div><!-- /.info-box-lines --></div><!-- /.info-box-content -->'."\n";
757				$openedDashBoard .= '	</div><!-- /.info-box -->'."\n";
758				$openedDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
759				$openedDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
760				$openedDashBoard .= "\n";
761			}
762		}
763
764		if ($showweather && !empty($isIntopOpenedDashBoard)) {
765			$appendClass = $conf->global->MAIN_DISABLE_METEO == 2 ? ' hideonsmartphone' : '';
766			$weather = getWeatherStatus($totallate);
767
768			$text = '';
769			if ($totallate > 0) {
770				$text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",
771						$totallate.(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? '%' : '')).')';
772			} else {
773				$text = $langs->transnoentitiesnoconv("NoItemLate");
774			}
775			$text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
776
777			$weatherDashBoard = '<div class="box-flex-item '.$appendClass.'"><div class="box-flex-item-with-margin">'."\n";
778			$weatherDashBoard .= '	<div class="info-box '.$openedDashBoardSize.' info-box-weather info-box-weather-level'.$weather->level.'">'."\n";
779			$weatherDashBoard .= '		<span class="info-box-icon">';
780			$weatherDashBoard .= img_weather('', $weather->level, '', 0, 'valignmiddle width50');
781			$weatherDashBoard .= '       </span>'."\n";
782			$weatherDashBoard .= '		<div class="info-box-content">'."\n";
783			$weatherDashBoard .= '			<div class="info-box-title">'.$langs->trans('GlobalOpenedElemView').'</div>'."\n";
784
785			if ($totallatePercentage > 0 && !empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) {
786				$weatherDashBoard .= '			<span class="info-box-number">'.$langs->transnoentitiesnoconv("NActionsLate",
787						price($totallatePercentage).'%').'</span>'."\n";
788				$weatherDashBoard .= '			<span class="progress-description">'.$langs->trans('NActionsLate',
789						$totalLateNumber).'</span>'."\n";
790			} else {
791				$weatherDashBoard .= '			<span class="info-box-number">'.$langs->transnoentitiesnoconv("NActionsLate",
792						$totalLateNumber).'</span>'."\n";
793				if ($totallatePercentage > 0) {
794					$weatherDashBoard .= '			<span class="progress-description">'.$langs->trans('NActionsLate',
795							price($totallatePercentage).'%').'</span>'."\n";
796				}
797			}
798
799			$weatherDashBoard .= '		</div><!-- /.info-box-content -->'."\n";
800			$weatherDashBoard .= '	</div><!-- /.info-box -->'."\n";
801			$weatherDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
802			$weatherDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
803			$weatherDashBoard .= "\n";
804
805			$openedDashBoard = $weatherDashBoard.$openedDashBoard;
806		}
807
808		if (!empty($isIntopOpenedDashBoard)) {
809			for ($i = 1; $i <= 10; $i++) {
810				$openedDashBoard .= '<div class="box-flex-item filler"></div>';
811			}
812		}
813
814		$nbworkboardcount = 0;
815		foreach ($valid_dashboardlines as $infoKey => $board) {
816			if (in_array($infoKey, $isIntopOpenedDashBoard)) {
817				// skip if info is present on top
818				continue;
819			}
820
821			if (empty($board->nbtodo)) {
822				$nbworkboardempty++;
823			}
824			$nbworkboardcount++;
825
826
827			$textlate = $langs->trans("NActionsLate", $board->nbtodolate);
828			$textlate .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')';
829
830
831			$boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats130 boxstatsborder">';
832			$boxwork .= '<div class="boxstatscontent">';
833			$boxwork .= '<span class="boxstatstext" title="'.dol_escape_htmltag($board->label).'">'.$board->img.' <span>'.$board->label.'</span></span><br>';
834			$boxwork .= '<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.$board->nbtodo.'</span></a>';
835			if ($board->total > 0 && !empty($conf->global->MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX)) {
836				$boxwork .= '&nbsp;/&nbsp;<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.price($board->total).'</span></a>';
837			}
838			$boxwork .= '</div>';
839			if ($board->nbtodolate > 0) {
840				$boxwork .= '<div class="dashboardlinelatecoin nowrap">';
841				$boxwork .= '<a title="'.dol_escape_htmltag($textlate).'" class="valignmiddle dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'" href="'.((!$board->url_late) ? $board->url : $board->url_late).'">';
842				//$boxwork .= img_picto($textlate, "warning_white", 'class="valigntextbottom"').'';
843				$boxwork .= img_picto($textlate, "warning_white",
844						'class="inline-block hideonsmartphone valigntextbottom"').'';
845				$boxwork .= '<span class="dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'">';
846				$boxwork .= $board->nbtodolate;
847				$boxwork .= '</span>';
848				$boxwork .= '</a>';
849				$boxwork .= '</div>';
850			}
851			$boxwork .= '</div></div>';
852			$boxwork .= "\n";
853		}
854
855		$boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
856		$boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
857		$boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
858		$boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
859
860		$boxwork .= '</div>';
861		$boxwork .= '</td></tr>';
862	} else {
863		$boxwork .= '<tr class="nohover">';
864		$boxwork .= '<td class="nohover valignmiddle opacitymedium">';
865		$boxwork .= $langs->trans("NoOpenedElementToProcess");
866		$boxwork .= '</td>';
867		$boxwork .= '</tr>';
868	}
869
870	$boxwork .= '</td></tr>';
871
872	$boxwork .= '</table>'; // End table array of working board
873	$boxwork .= '</div>';
874
875	if (!empty($isIntopOpenedDashBoard)) {
876		print '<div class="fichecenter">';
877		print '<div class="opened-dash-board-wrap"><div class="box-flex-container">'.$openedDashBoard.'</div></div>';
878		print '</div>';
879	}
880}
881
882
883print '<div class="clearboth"></div>';
884
885print '<div class="fichecenter fichecenterbis">';
886
887
888/*
889 * Show widgets (boxes)
890 */
891
892$boxlist .= '<div class="twocolumns">';
893
894$boxlist .= '<div class="firstcolumn fichehalfleft boxhalfleft" id="boxhalfleft">';
895if (!empty($nbworkboardcount))
896{
897	$boxlist .= $boxwork;
898}
899
900$boxlist .= $resultboxes['boxlista'];
901
902$boxlist .= '</div>';
903
904
905if (empty($user->socid) && empty($conf->global->MAIN_DISABLE_GLOBAL_BOXSTATS))
906{
907	// Remove allready present info in new dash board
908	if (!empty($conf->global->MAIN_INCLUDE_GLOBAL_STATS_IN_OPENED_DASHBOARD) && is_array($boxstatItems) && count($boxstatItems) > 0) {
909		foreach ($boxstatItems as $boxstatItemKey => $boxstatItemHtml) {
910			if (in_array($boxstatItemKey, $globalStatInTopOpenedDashBoard)) {
911				unset($boxstatItems[$boxstatItemKey]);
912			}
913		}
914	}
915
916	if (!empty($boxstatFromHook) || !empty($boxstatItems)) {
917		$boxstat .= '<!-- Database statistics -->'."\n";
918		$boxstat .= '<div class="box">';
919		$boxstat .= '<table summary="'.dol_escape_htmltag($langs->trans("DolibarrStateBoard")).'" class="noborder boxtable boxtablenobottom nohover widgetstats" width="100%">';
920		$boxstat .= '<tr class="liste_titre box_titre">';
921		$boxstat .= '<td>';
922		$boxstat .= '<div class="inline-block valignmiddle">'.$langs->trans("DolibarrStateBoard").'</div>';
923		$boxstat .= '</td>';
924		$boxstat .= '</tr>';
925		$boxstat .= '<tr class="nobottom nohover"><td class="tdboxstats nohover flexcontainer">';
926
927		$boxstat .= $boxstatFromHook;
928
929		if (is_array($boxstatItems) && count($boxstatItems) > 0)
930		{
931			$boxstat .= implode('', $boxstatItems);
932		}
933
934		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
935		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
936		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
937		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
938		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
939		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
940		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
941		$boxstat .= '<a class="boxstatsindicator thumbstat nobold nounderline"><div class="boxstatsempty"></div></a>';
942
943		$boxstat .= '</td></tr>';
944		$boxstat .= '</table>';
945		$boxstat .= '</div>';
946	}
947}
948
949$boxlist .= '<div class="secondcolumn fichehalfright boxhalfright" id="boxhalfright">';
950
951$boxlist .= $boxstat;
952$boxlist .= $resultboxes['boxlistb'];
953
954$boxlist .= '</div>';
955$boxlist .= "\n";
956
957$boxlist .= '</div>';
958
959
960print $boxlist;
961
962print '</div>';
963
964
965/*
966 * Show security warnings
967 */
968
969// Security warning repertoire install existe (si utilisateur admin)
970if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING))
971{
972	$message = '';
973
974	// Check if install lock file is present
975	$lockfile = DOL_DATA_ROOT.'/install.lock';
976	if (!empty($lockfile) && !file_exists($lockfile) && is_dir(DOL_DOCUMENT_ROOT."/install"))
977	{
978		$langs->load("errors");
979		//if (! empty($message)) $message.='<br>';
980		$message .= info_admin($langs->trans("WarningLockFileDoesNotExists", DOL_DATA_ROOT).' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
981	}
982
983	// Conf files must be in read only mode
984	if (is_writable($conffile))
985	{
986		$langs->load("errors");
987		//$langs->load("other");
988		//if (! empty($message)) $message.='<br>';
989		$message .= info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
990	}
991
992	if ($message)
993	{
994		print $message;
995		//$message.='<br>';
996		//print info_admin($langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install"));
997	}
998}
999
1000//print 'mem='.memory_get_usage().' - '.memory_get_peak_usage();
1001
1002// End of page
1003llxFooter();
1004$db->close();
1005
1006
1007/**
1008 *  Show weather logo. Logo to show depends on $totallate and values for
1009 *  $conf->global->MAIN_METEO_LEVELx
1010 *
1011 *  @param      int     $totallate      Nb of element late
1012 *  @param      string  $text           Text to show on logo
1013 *  @param      string  $options        More parameters on img tag
1014 *  @param      string  $morecss        More CSS
1015 *  @return     string                  Return img tag of weather
1016 */
1017function showWeather($totallate, $text, $options, $morecss = '')
1018{
1019	global $conf;
1020
1021	$weather = getWeatherStatus($totallate);
1022	return img_weather($text, $weather->picto, $options, 0, $morecss);
1023}
1024
1025
1026/**
1027 *  get weather level
1028 *  $conf->global->MAIN_METEO_LEVELx
1029 *
1030 *  @param      int     $totallate      Nb of element late
1031 *  @return     string                  Return img tag of weather
1032 */
1033function getWeatherStatus($totallate)
1034{
1035	global $conf;
1036
1037	$weather = new stdClass();
1038	$weather->picto = '';
1039
1040	$offset = 0;
1041	$factor = 10; // By default
1042
1043	$used_conf = !empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL';
1044
1045	$level0 = $offset;
1046	$weather->level = 0;
1047	if (!empty($conf->global->{$used_conf.'0'})) {
1048		$level0 = $conf->global->{$used_conf.'0'};
1049	}
1050	$level1 = $offset + 1 * $factor;
1051	if (!empty($conf->global->{$used_conf.'1'})) {
1052		$level1 = $conf->global->{$used_conf.'1'};
1053	}
1054	$level2 = $offset + 2 * $factor;
1055	if (!empty($conf->global->{$used_conf.'2'})) {
1056		$level2 = $conf->global->{$used_conf.'2'};
1057	}
1058	$level3 = $offset + 3 * $factor;
1059	if (!empty($conf->global->{$used_conf.'3'})) {
1060		$level3 = $conf->global->{$used_conf.'3'};
1061	}
1062
1063	if ($totallate <= $level0) {
1064		$weather->picto = 'weather-clear.png';
1065		$weather->level = 0;
1066	}
1067	elseif ($totallate <= $level1) {
1068		$weather->picto = 'weather-few-clouds.png';
1069		$weather->level = 1;
1070	}
1071	elseif ($totallate <= $level2) {
1072		$weather->picto = 'weather-clouds.png';
1073		$weather->level = 2;
1074	}
1075	elseif ($totallate <= $level3) {
1076		$weather->picto = 'weather-many-clouds.png';
1077		$weather->level = 3;
1078	}
1079	else {
1080		$weather->picto = 'weather-storm.png';
1081		$weather->level = 4;
1082	}
1083
1084	return $weather;
1085}
1086