dolibarr 21.0.3
index.php
Go to the documentation of this file.
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 * Copyright (C) 2021-2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
31define('CSRFCHECK_WITH_TOKEN', 1); // We force need to use a token to login when making a POST
32
33require 'main.inc.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
35
44// If not defined, we select menu "home"
45$_GET['mainmenu'] = GETPOST('mainmenu', 'aZ09') ? GETPOST('mainmenu', 'aZ09') : 'home'; // Keep this ?
46$action = GETPOST('action', 'aZ09');
47
48$hookmanager->initHooks(array('index'));
49
50
51/*
52 * Actions
53 */
54
55// Define $nbmodulesnotautoenabled - TODO This code is at different places
56$nbmodulesnotautoenabled = count($conf->modules);
57$listofmodulesautoenabled = array('agenda', 'fckeditor', 'export', 'import');
58foreach ($listofmodulesautoenabled as $moduleautoenable) {
59 if (in_array($moduleautoenable, $conf->modules)) {
60 $nbmodulesnotautoenabled--;
61 }
62}
63
64// Check if company name is defined (first install)
65if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) {
66 header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
67 exit;
68}
69if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only autoenabled modules (property ->enabled_bydefault in modules) are activated
70 header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
71 exit;
72}
73if (GETPOST('addbox')) { // Add box (when submit is done from a form when ajax disabled)
74 require_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php';
75 $zone = GETPOSTINT('areacode');
76 $userid = GETPOSTINT('userid');
77 $boxorder = GETPOST('boxorder', 'aZ09');
78 $boxorder .= GETPOST('boxcombo', 'aZ09');
79
80 $result = InfoBox::saveboxorder($db, $zone, $boxorder, $userid);
81 if ($result > 0) {
82 setEventMessages($langs->trans("BoxAdded"), null);
83 }
84}
85
86
87/*
88 * View
89 */
90
91if (!isset($form) || !is_object($form)) {
92 $form = new Form($db);
93}
94
95$appli = constant('DOL_APPLICATION_TITLE');
96$applicustom = getDolGlobalString('MAIN_APPLICATION_TITLE');
97if ($applicustom) {
98 $appli = (preg_match('/^\+/', $applicustom) ? $appli : '').$applicustom;
99} else {
100 $appli .= " ".DOL_VERSION;
101}
102
103// Title
104$title = $langs->trans("HomeArea").' - '.$appli;
105
106llxHeader('', $title);
107
108
109$resultboxes = FormOther::getBoxesArea($user, "0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb)
110
111
112if (getDolGlobalString('MAIN_MOTD')) {
113 $conf->global->MAIN_MOTD = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>/i', '<br>', getDolGlobalString('MAIN_MOTD'));
114 if (getDolGlobalString('MAIN_MOTD')) {
115 $substitutionarray = getCommonSubstitutionArray($langs);
116 complete_substitutions_array($substitutionarray, $langs);
117 $texttoshow = make_substitutions(getDolGlobalString('MAIN_MOTD'), $substitutionarray, $langs);
118
119 print "\n<!-- Start of welcome text -->\n";
120 print '<table class="centpercent notopnoleftnoright"><tr><td>';
121 print dol_htmlentitiesbr($texttoshow);
122 print '</td></tr></table><br>';
123 print "\n<!-- End of welcome text -->\n";
124 }
125}
126
127/*
128 * Show specific warnings
129 */
130
131// Specific warning to propose to upgrade invoice situation to progressive mode
132if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
133 $langs->loadLangs(array("admin"));
134 print info_admin($langs->trans("WarningExperimentalFeatureInvoiceSituationNeedToUpgradeToProgressiveMode", 'https://partners.dolibarr.org'));
135 //print "<br>";
136}
137
138/*
139 * Show security warnings
140 */
141
142// Security warning if install.lock file is missing or if conf file is writable
143if (!getDolGlobalString('MAIN_REMOVE_INSTALL_WARNING')) {
144 $message = '';
145
146 // Check if install lock file is present
147 $lockfile = DOL_DATA_ROOT.'/install.lock';
148 if (!empty($lockfile) && !file_exists($lockfile) && is_dir(DOL_DOCUMENT_ROOT."/install")) {
149 $langs->load("errors");
150 //if (!empty($message)) $message.='<br>';
151 $message .= info_admin($langs->transnoentities("WarningLockFileDoesNotExists", DOL_DATA_ROOT).' '.$langs->transnoentities("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
152 }
153
154 // Conf files must be in read only mode
155 if (is_writable($conffile)) { // $conffile is defined into filefunc.inc.php
156 $langs->load("errors");
157 //$langs->load("other");
158 //if (!empty($message)) $message.='<br>';
159 $message .= info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->transnoentities("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
160 }
161
162 $object = new stdClass();
163 $parameters = array();
164 $reshook = $hookmanager->executeHooks('infoadmin', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
165 if ($reshook == 0) {
166 $message .= $hookmanager->resPrint;
167 }
168 if ($message) { // $message is an HTML string.
169 print '<!-- show security warning -->';
170 print dol_string_onlythesehtmltags($message, 1, 0, 0, 0, array('div', 'span', 'b'));
171 //print '<br>';
172 //print info_admin($langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install"));
173 }
174}
175
176/*
177 * Dashboard Dolibarr statistics
178 * Hidden for external users
179 */
180
181print load_fiche_titre('&nbsp;', $resultboxes['selectboxlist'], '', 0, '', 'titleforhome');
182
183// Load translation files required by page
184$langs->loadLangs(array('commercial', 'bills', 'orders', 'contracts'));
185
186// Dolibarr Working Board with weather
187if (!getDolGlobalString('MAIN_DISABLE_GLOBAL_WORKBOARD') && getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
188 $showweather = (!getDolGlobalString('MAIN_DISABLE_METEO') || getDolGlobalInt('MAIN_DISABLE_METEO') == 2) ? 1 : 0;
189
190 // Array that contains all WorkboardResponse classes to process them
191 $dashboardlines = array();
192
193 // Do not include sections without management permission
194 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
195
196 // Number of actions to do (late)
197 if (isModEnabled('agenda') && !getDolGlobalString('MAIN_DISABLE_BLOCK_AGENDA') && $user->hasRight('agenda', 'myactions', 'read')) {
198 include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
199 $board = new ActionComm($db);
200 $dashboardlines[$board->element] = $board->load_board($user);
201 }
202
203 // Number of project opened
204 if (isModEnabled('project') && !getDolGlobalString('MAIN_DISABLE_BLOCK_PROJECT') && $user->hasRight('projet', 'lire')) {
205 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
206 $board = new Project($db);
207 $dashboardlines[$board->element] = $board->load_board($user);
208 }
209
210 // Number of tasks to do (late)
211 if (isModEnabled('project') && !getDolGlobalString('MAIN_DISABLE_BLOCK_PROJECT') && !getDolGlobalString('PROJECT_HIDE_TASKS') && $user->hasRight('projet', 'lire')) {
212 include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
213 $board = new Task($db);
214 $dashboardlines[$board->element] = $board->load_board($user);
215 }
216
217 // Number of commercial customer proposals open (expired)
218 if (isModEnabled('propal') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('propal', 'read')) {
219 include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
220 $board = new Propal($db);
221 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
222 // Number of commercial proposals CLOSED signed (billed)
223 $dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
224 }
225
226 // Number of supplier proposals open (expired)
227 if (isModEnabled('supplier_proposal') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('supplier_proposal', 'lire')) {
228 $langs->load("supplier_proposal");
229 include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
230 $board = new SupplierProposal($db);
231 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
232 // Number of commercial proposals CLOSED signed (billed)
233 $dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
234 }
235
236 // Number of sales orders
237 if (isModEnabled('order') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('commande', 'lire')) {
238 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
239 $board = new Commande($db);
240 // Number of customer orders to be shipped (validated and in progress)
241 $dashboardlines[$board->element.'_toship'] = $board->load_board($user, 'toship');
242 // Number of customer orders to be billed (not visible by default, does not match a lot of organization).
243 if (getDolGlobalInt('ORDER_BILL_AFTER_VALIDATION')) {
244 $dashboardlines[$board->element.'_tobill'] = $board->load_board($user, 'tobill');
245 }
246 // Number of customer orders to be billed (delivered but not billed)
247 $dashboardlines[$board->element.'_shippedtobill'] = $board->load_board($user, 'shippedtobill');
248 }
249
250 // Number of suppliers orders
251 if (isModEnabled('supplier_order') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('fournisseur', 'commande', 'lire')) {
252 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
253 $board = new CommandeFournisseur($db);
254 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
255 $dashboardlines[$board->element.'_awaiting'] = $board->load_board($user, 'awaiting');
256 }
257
258 // Number of contract / services enabled (delayed)
259 if (isModEnabled('contract') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CONTRACT') && $user->hasRight('contrat', 'lire')) {
260 include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
261 $board = new Contrat($db);
262 $dashboardlines[$board->element.'_inactive'] = $board->load_board($user, "inactive");
263 // Number of active services (expired)
264 $dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
265 }
266
267 // Number of tickets open
268 if (isModEnabled('ticket') && !getDolGlobalString('MAIN_DISABLE_BLOCK_TICKET') && $user->hasRight('ticket', 'read')) {
269 include_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
270 $board = new Ticket($db);
271 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
272 // Number of active services (expired)
273 //$dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
274 }
275
276 // Number of invoices customers (paid)
277 if (isModEnabled('invoice') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('facture', 'lire')) {
278 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
279 $board = new Facture($db);
280 $dashboardlines[$board->element] = $board->load_board($user);
281 }
282
283 // Number of supplier invoices (paid)
284 if (isModEnabled('supplier_invoice') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('fournisseur', 'facture', 'lire')) {
285 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
286 $board = new FactureFournisseur($db);
287 $dashboardlines[$board->element] = $board->load_board($user);
288 }
289
290 // Number of transactions to conciliate
291 if (isModEnabled('bank') && !getDolGlobalString('MAIN_DISABLE_BLOCK_BANK') && $user->hasRight('banque', 'lire') && !$user->socid) {
292 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
293 $board = new Account($db);
294 $nb = $board->countAccountToReconcile(); // Get nb of account to reconciliate
295 if ($nb > 0) {
296 $dashboardlines[$board->element] = $board->load_board($user);
297 }
298 }
299
300
301 // Number of cheque to send
302 if (isModEnabled('bank') && !getDolGlobalString('MAIN_DISABLE_BLOCK_BANK') && $user->hasRight('banque', 'lire') && !$user->socid) {
303 if (!getDolGlobalString('BANK_DISABLE_CHECK_DEPOSIT')) {
304 include_once DOL_DOCUMENT_ROOT . '/compta/paiement/cheque/class/remisecheque.class.php';
305 $board = new RemiseCheque($db);
306 $dashboardlines[$board->element] = $board->load_board($user);
307 }
308 if (isModEnabled('prelevement')) {
309 include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
310 $board = new BonPrelevement($db);
311 $dashboardlines[$board->element . '_direct_debit'] = $board->load_board($user, 'direct_debit');
312 }
313 if (isModEnabled('paymentbybanktransfer')) {
314 include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
315 $board = new BonPrelevement($db);
316 $dashboardlines[$board->element . '_credit_transfer'] = $board->load_board($user, 'credit_transfer');
317 }
318 }
319
320 // Number of foundation members
321 if (isModEnabled('member') && !getDolGlobalString('MAIN_DISABLE_BLOCK_ADHERENT') && $user->hasRight('adherent', 'lire') && !$user->socid) {
322 include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
323 $board = new Adherent($db);
324 $dashboardlines[$board->element.'_shift'] = $board->load_board($user, 'shift');
325 $dashboardlines[$board->element.'_expired'] = $board->load_board($user, 'expired');
326 }
327
328 // Number of expense reports to approve
329 if (isModEnabled('expensereport') && !getDolGlobalString('MAIN_DISABLE_BLOCK_EXPENSEREPORT') && $user->hasRight('expensereport', 'approve')) {
330 include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
331 $board = new ExpenseReport($db);
332 $dashboardlines[$board->element.'_toapprove'] = $board->load_board($user, 'toapprove');
333 }
334
335 // Number of expense reports to pay
336 if (isModEnabled('expensereport') && !getDolGlobalString('MAIN_DISABLE_BLOCK_EXPENSEREPORT') && $user->hasRight('expensereport', 'to_paid')) {
337 include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
338 $board = new ExpenseReport($db);
339 $dashboardlines[$board->element.'_topay'] = $board->load_board($user, 'topay');
340 }
341
342 // Number of holidays to approve
343 if (isModEnabled('holiday') && !getDolGlobalString('MAIN_DISABLE_BLOCK_HOLIDAY') && $user->hasRight('holiday', 'approve')) {
344 include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
345 $board = new Holiday($db);
346 $dashboardlines[$board->element] = $board->load_board($user);
347 }
348
349 $object = new stdClass();
350 $parameters = array();
351 $action = '';
352 $reshook = $hookmanager->executeHooks(
353 'addOpenElementsDashboardLine',
354 $parameters,
355 $object,
356 $action
357 ); // Note that $action and $object may have been modified by some hooks
358 if ($reshook == 0) {
359 $dashboardlines = array_merge($dashboardlines, $hookmanager->resArray);
360 }
361
362 /* Open object dashboard */
363 $dashboardgroup = array(
364 'action' =>
365 array(
366 'groupName' => 'Agenda',
367 'stats' => array('action'),
368 ),
369 'project' =>
370 array(
371 'groupName' => 'Projects',
372 'globalStatsKey' => 'projects',
373 'stats' => array('project', 'project_task'),
374 ),
375 'propal' =>
376 array(
377 'groupName' => 'Proposals',
378 'globalStatsKey' => 'proposals',
379 'stats' =>
380 array('propal_opened', 'propal_signed'),
381 ),
382 'commande' =>
383 array(
384 'groupName' => 'Orders',
385 'globalStatsKey' => 'orders',
386 'stats' =>
387 array('commande_toship', 'commande_tobill', 'commande_shippedtobill'),
388 ),
389 'facture' =>
390 array(
391 'groupName' => 'Invoices',
392 'globalStatsKey' => 'invoices',
393 'stats' =>
394 array('facture'),
395 ),
396 'supplier_proposal' =>
397 array(
398 'lang' => 'supplier_proposal',
399 'groupName' => 'SupplierProposals',
400 'globalStatsKey' => 'askprice',
401 'stats' =>
402 array('supplier_proposal_opened', 'supplier_proposal_signed'),
403 ),
404 'order_supplier' =>
405 array(
406 'groupName' => 'SuppliersOrders',
407 'globalStatsKey' => 'supplier_orders',
408 'stats' =>
409 array('order_supplier_opened', 'order_supplier_awaiting'),
410 ),
411 'invoice_supplier' =>
412 array(
413 'groupName' => 'BillsSuppliers',
414 'globalStatsKey' => 'supplier_invoices',
415 'stats' =>
416 array('invoice_supplier'),
417 ),
418 'contrat' =>
419 array(
420 'groupName' => 'Contracts',
421 'globalStatsKey' => 'Contracts',
422 'stats' =>
423 array('contrat_inactive', 'contrat_active'),
424 ),
425 'ticket' =>
426 array(
427 'groupName' => 'Tickets',
428 'globalStatsKey' => 'ticket',
429 'stats' =>
430 array('ticket_opened'),
431 ),
432 'bank_account' =>
433 array(
434 'groupName' => 'BankAccount',
435 'stats' =>
436 array('bank_account', 'chequereceipt', 'widthdraw_direct_debit', 'widthdraw_credit_transfer'),
437 ),
438 'member' =>
439 array(
440 'groupName' => 'Members',
441 'globalStatsKey' => 'members',
442 'stats' =>
443 array('member_shift', 'member_expired'),
444 ),
445 'expensereport' =>
446 array(
447 'groupName' => 'ExpenseReport',
448 'globalStatsKey' => 'expensereports',
449 'stats' =>
450 array('expensereport_toapprove', 'expensereport_topay'),
451 ),
452 'holiday' =>
453 array(
454 'groupName' => 'Holidays',
455 'globalStatsKey' => 'holidays',
456 'stats' =>
457 array('holiday'),
458 ),
459 );
460
461 $object = new stdClass();
462 $parameters = array(
463 'dashboardgroup' => $dashboardgroup
464 );
465 $reshook = $hookmanager->executeHooks('addOpenElementsDashboardGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
466 if ($reshook == 0) {
467 $dashboardgroup = array_merge($dashboardgroup, $hookmanager->resArray);
468 }
469
470
471 // Calculate total nb of late
472 $totallate = $totaltodo = 0;
473
474 //Remove any invalid response
475 //load_board can return an integer if failed, or WorkboardResponse if OK
476 $valid_dashboardlines = array();
477 foreach ($dashboardlines as $workboardid => $tmp) {
478 if ($tmp instanceof WorkboardResponse) {
479 $tmp->id = $workboardid; // Complete the object to add its id into its name
480 $valid_dashboardlines[$workboardid] = $tmp;
481 }
482 }
483
484 // We calculate $totallate. Must be defined before start of next loop because it is show in first fetch on next loop
485 foreach ($valid_dashboardlines as $board) {
486 if (is_numeric($board->nbtodo) && is_numeric($board->nbtodolate) && $board->nbtodolate > 0) {
487 $totaltodo += $board->nbtodo;
488 $totallate += $board->nbtodolate;
489 }
490 }
491
492 $openedDashBoardSize = 'info-box-sm'; // use sm by default
493 foreach ($dashboardgroup as $dashbordelement) {
494 if (is_array($dashbordelement['stats']) && count($dashbordelement['stats']) > 2) {
495 $openedDashBoardSize = ''; // use default info box size : big
496 break;
497 }
498 }
499
500 $totalLateNumber = $totallate;
501 $totallatePercentage = ((!empty($totaltodo)) ? round($totallate / $totaltodo * 100, 2) : 0);
502 if (getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE')) {
503 $totallate = $totallatePercentage;
504 }
505
506 // Fill the content to show the tasks to do as a widget box (old version). Now this is no more used. Tasks to do ar in dedicated thumbs.
507 $boxwork = '';
508 $boxwork .= '<div class="box">';
509 $boxwork .= '<table summary="'.dol_escape_htmltag($langs->trans("WorkingBoard")).'" class="noborder boxtable boxtablenobottom boxworkingboard centpercent">'."\n";
510 $boxwork .= '<tr class="liste_titre">';
511 $boxwork .= '<th class="liste_titre"><div class="inline-block valignmiddle">'.$langs->trans("DolibarrWorkBoard").'</div>';
512 if ($showweather) {
513 if ($totallate > 0) {
514 $text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv(
515 "NActionsLate",
516 $totallate.(getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? '%' : '')
517 ).')';
518 } else {
519 $text = $langs->transnoentitiesnoconv("NoItemLate");
520 }
521 $text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
522 //$text.=$form->textwithpicto('',$langs->trans("LateDesc"));
523 $options = 'height="24px" style="float: right"';
524 $boxwork .= showWeather($totallate, $text, $options, 'inline-block valignmiddle');
525 }
526 $boxwork .= '</th>';
527 $boxwork .= '</tr>'."\n";
528
529 // Show dashboard
530 $nbworkboardempty = 0;
531 $isIntopOpenedDashBoard = $globalStatInTopOpenedDashBoard = array();
532 $openedDashBoard = '';
533 if (!empty($valid_dashboardlines)) {
534 $boxwork .= '<tr class="nobottom nohover"><td class="tdboxstats nohover flexcontainer centpercent"><div style="display: flex: flex-wrap: wrap">';
535
536 foreach ($dashboardgroup as $groupKey => $groupElement) {
537 $boards = array();
538
539 // Scan $groupElement and save the one with 'stats' that must be used for the open objects dashboard
540 if (!getDolGlobalString('MAIN_DISABLE_NEW_OPENED_DASH_BOARD')) {
541 foreach ($groupElement['stats'] as $infoKey) {
542 if (!empty($valid_dashboardlines[$infoKey])) {
543 $boards[] = $valid_dashboardlines[$infoKey];
544 $isIntopOpenedDashBoard[] = $infoKey;
545 }
546 }
547 }
548
549 if (!empty($boards)) {
550 if (!empty($groupElement['lang'])) {
551 $langs->load($groupElement['lang']);
552 }
553 // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset
554 $groupName = $langs->trans($groupElement['groupName']);
555 $groupKeyLowerCase = strtolower($groupKey);
556
557 // global stats
558 $globalStatsKey = false;
559 if (!empty($groupElement['globalStatsKey']) && empty($groupElement['globalStats'])) { // can be filled by hook
560 $globalStatsKey = $groupElement['globalStatsKey'];
561 $groupElement['globalStats'] = array();
562 }
563
564 $openedDashBoard .= '<div class="box-flex-item"><div class="box-flex-item-with-margin">'."\n";
565 $openedDashBoard .= ' <div class="info-box '.$openedDashBoardSize.'">'."\n";
566 $openedDashBoard .= ' <span class="info-box-icon bg-infobox-'.$groupKeyLowerCase.'">'."\n";
567 $openedDashBoard .= ' <i class="fa fa-dol-'.$groupKeyLowerCase.'"></i>'."\n";
568
569 // Show the span for the total of record. TODO This seems not used.
570 if (!empty($groupElement['globalStats'])) {
571 $globalStatInTopOpenedDashBoard[] = $globalStatsKey;
572 $openedDashBoard .= '<span class="info-box-icon-text" title="'.$groupElement['globalStats']['text'].'">'.$groupElement['globalStats']['nbTotal'].'</span>';
573 }
574
575 $openedDashBoard .= '</span>'."\n";
576 $openedDashBoard .= '<div class="info-box-content">'."\n";
577
578 $openedDashBoard .= '<div class="info-box-title" title="'.dolPrintHTMLForAttribute($groupName).'">'.$groupName.'</div>'."\n";
579 $openedDashBoard .= '<div class="info-box-lines">'."\n";
580
581 foreach ($boards as $board) {
582 $openedDashBoard .= '<div class="info-box-line spanoverflow nowrap">';
583
584 if (!empty($board->labelShort)) {
585 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text" title="'.$board->label.'">'.$board->labelShort.'</div>';
586 } else {
587 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text">'.$board->label.'</div>';
588 }
589
590 $textLateTitle = $langs->trans("NActionsLate", $board->nbtodolate);
591 $textLateTitle .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil(empty($board->warning_delay) ? 0 : $board->warning_delay) >= 0 ? '+' : '').ceil(empty($board->warning_delay) ? 0 : $board->warning_delay).' '.$langs->trans("days").')';
592
593 if ($board->id == 'bank_account') {
594 $textLateTitle .= '<br><span class="opacitymedium">'.$langs->trans("IfYouDontReconcileDisableProperty", $langs->transnoentitiesnoconv("Conciliable")).'</span>';
595 }
596
597 $textLate = '';
598 if ($board->nbtodolate > 0) {
599 $textLate .= '<span title="'.dol_escape_htmltag($textLateTitle).'" class="classfortooltip badge badge-warning">';
600 $textLate .= '<i class="fa fa-exclamation-triangle hideonsmartphone"></i> '.$board->nbtodolate;
601 $textLate .= '</span>';
602 }
603
604 $nbtodClass = '';
605 if ($board->nbtodo > 0) {
606 $nbtodClass = 'badge badge-info';
607 } else {
608 $nbtodClass = 'opacitymedium';
609 }
610
611 // Forge the line to show into the open object box
612 $labeltoshow = $board->label.' ('.$board->nbtodo.')';
613 if ($board->total > 0) {
614 $labeltoshow .= ' - '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
615 }
616 $openedDashBoard .= '<a href="'.$board->url.'" class="info-box-text info-box-text-a">';
617 $openedDashBoard .= $infoName;
618 $openedDashBoard .= '<div class="inline-block nowraponall">';
619 $openedDashBoard .= '<span class="classfortooltip'.($nbtodClass ? ' '.$nbtodClass : '').'" title="'.$labeltoshow.'">';
620 $openedDashBoard .= $board->nbtodo;
621 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
622 $openedDashBoard .= ' : '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
623 }
624 $openedDashBoard .= '</span>';
625
626 if ($textLate) {
627 if ($board->url_late) {
628 $openedDashBoard .= '</div></a>';
629 $openedDashBoard .= ' <div class="inline-block"><a href="'.$board->url_late.'" class="info-box-text info-box-text-a paddingleft">';
630 } else {
631 $openedDashBoard .= ' ';
632 }
633 $openedDashBoard .= $textLate;
634 }
635 $openedDashBoard .= '</a>'."\n";
636 $openedDashBoard .= '</div>';
637 $openedDashBoard .= '</div>'."\n";
638 }
639
640 // TODO Add hook here to add more "info-box-line"
641
642 $openedDashBoard .= ' </div><!-- /.info-box-lines --></div><!-- /.info-box-content -->'."\n";
643 $openedDashBoard .= ' </div><!-- /.info-box -->'."\n";
644 $openedDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
645 $openedDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
646 $openedDashBoard .= "\n";
647 }
648 }
649
650 if ($showweather && !empty($isIntopOpenedDashBoard)) {
651 $appendClass = (getDolGlobalInt('MAIN_DISABLE_METEO') == 2 ? ' hideonsmartphone' : '');
652 $weather = getWeatherStatus($totallate);
653
654 $text = '';
655 if ($totallate > 0) {
656 $text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv(
657 "NActionsLate",
658 $totallate.(getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? '%' : '')
659 ).')';
660 } else {
661 $text = $langs->transnoentitiesnoconv("NoItemLate");
662 }
663 $text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
664
665 $weatherDashBoard = '<div class="box-flex-item '.$appendClass.'"><div class="box-flex-item-with-margin">'."\n";
666 $weatherDashBoard .= ' <div class="info-box '.$openedDashBoardSize.' info-box-weather info-box-weather-level'.$weather->level.'">'."\n";
667 $weatherDashBoard .= ' <span class="info-box-icon">';
668 $weatherDashBoard .= img_weather('', $weather->level, '', 0, 'valignmiddle width50');
669 $weatherDashBoard .= ' </span>'."\n";
670 $weatherDashBoard .= ' <div class="info-box-content">'."\n";
671 $weatherDashBoard .= ' <div class="info-box-title">'.$langs->trans('GlobalOpenedElemView').'</div>'."\n";
672
673 if ($totallatePercentage > 0 && getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE')) {
674 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
675 "NActionsLate",
676 price($totallatePercentage).'%'
677 ).'</span>'."\n";
678 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
679 'NActionsLate',
680 $totalLateNumber
681 ).'</span>'."\n";
682 } else {
683 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
684 "NActionsLate",
685 $totalLateNumber
686 ).'</span>'."\n";
687 if ($totallatePercentage > 0) {
688 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
689 'NActionsLate',
690 price($totallatePercentage).'%'
691 ).'</span>'."\n";
692 }
693 }
694
695 $weatherDashBoard .= ' </div><!-- /.info-box-content -->'."\n";
696 $weatherDashBoard .= ' </div><!-- /.info-box -->'."\n";
697 $weatherDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
698 $weatherDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
699 $weatherDashBoard .= "\n";
700
701 $openedDashBoard = $weatherDashBoard.$openedDashBoard;
702 }
703
704 if (!empty($isIntopOpenedDashBoard)) {
705 for ($i = 1; $i <= 10; $i++) {
706 $openedDashBoard .= '<div class="box-flex-item filler"></div>';
707 }
708 }
709
710 $nbworkboardcount = 0;
711 foreach ($valid_dashboardlines as $infoKey => $board) {
712 if (in_array($infoKey, $isIntopOpenedDashBoard)) {
713 // skip if info is present on top
714 continue;
715 }
716
717 if (empty($board->nbtodo)) {
718 $nbworkboardempty++;
719 }
720 $nbworkboardcount++;
721
722
723 $textlate = $langs->trans("NActionsLate", $board->nbtodolate);
724 $textlate .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')';
725
726
727 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats130 boxstatsborder">';
728 $boxwork .= '<div class="boxstatscontent">';
729 $boxwork .= '<span class="boxstatstext" title="'.dol_escape_htmltag($board->label).'">'.$board->img.' <span>'.$board->label.'</span></span><br>';
730 $boxwork .= '<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.$board->nbtodo.'</span></a>';
731 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
732 $boxwork .= '&nbsp;/&nbsp;<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.price($board->total).'</span></a>';
733 }
734 $boxwork .= '</div>';
735 if ($board->nbtodolate > 0) {
736 $boxwork .= '<div class="dashboardlinelatecoin nowrap">';
737 $boxwork .= '<a title="'.dol_escape_htmltag($textlate).'" class="valignmiddle dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'" href="'.((!$board->url_late) ? $board->url : $board->url_late).'">';
738 //$boxwork .= img_picto($textlate, "warning_white", 'class="valigntextbottom"');
739 $boxwork .= img_picto(
740 $textlate,
741 "warning_white",
742 'class="inline-block hideonsmartphone valigntextbottom"'
743 );
744 $boxwork .= '<span class="dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'">';
745 $boxwork .= $board->nbtodolate;
746 $boxwork .= '</span>';
747 $boxwork .= '</a>';
748 $boxwork .= '</div>';
749 }
750 $boxwork .= '</div></div>';
751 $boxwork .= "\n";
752 }
753
754 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
755 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
756 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
757 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
758
759 $boxwork .= '</div>';
760 $boxwork .= '</td></tr>';
761 } else {
762 $boxwork .= '<tr class="nohover">';
763 $boxwork .= '<td class="nohover valignmiddle opacitymedium">';
764 $boxwork .= $langs->trans("NoOpenedElementToProcess");
765 $boxwork .= '</td>';
766 $boxwork .= '</tr>';
767 }
768
769 $boxwork .= '</td></tr>';
770
771 $boxwork .= '</table>'; // End table array of working board
772 $boxwork .= '</div>';
773
774 if (!empty($isIntopOpenedDashBoard)) {
775 print '<div class="fichecenter">';
776 print '<div class="opened-dash-board-wrap"><div class="box-flex-container">'.$openedDashBoard.'</div></div>';
777 print '</div>';
778 }
779}
780
781
782print '<div class="clearboth"></div>';
783
784print '<div class="fichecenter fichecenterbis">';
785
786
787/*
788 * Show widgets (boxes)
789 */
790
791$boxlist = '<div class="twocolumns">';
792
793$boxlist .= '<div class="firstcolumn fichehalfleft boxhalfleft" id="boxhalfleft">';
794if (!empty($nbworkboardcount)) {
795 $boxlist .= $boxwork;
796}
797
798$boxlist .= $resultboxes['boxlista'];
799
800$boxlist .= '</div>';
801
802$boxlist .= '<div class="secondcolumn fichehalfright boxhalfright" id="boxhalfright">';
803
804$boxlist .= $resultboxes['boxlistb'];
805
806$boxlist .= '</div>';
807$boxlist .= "\n";
808
809$boxlist .= '</div>';
810
811
812print $boxlist;
813
814print '</div>';
815
816//print 'mem='.memory_get_usage().' - '.memory_get_peak_usage();
817
818// End of page
819llxFooter();
820$db->close();
821
822
833function showWeather($totallate, $text, $options, $morecss = '')
834{
835 global $conf;
836
837 $weather = getWeatherStatus($totallate);
838 return img_weather($text, $weather->picto, $options, 0, $morecss);
839}
840
841
848function getWeatherStatus($totallate)
849{
850 $weather = new stdClass();
851 $weather->picto = '';
852
853 $offset = 0;
854 $factor = 10; // By default
855
856 $used_conf = (getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL');
857
858 $weather->level = 0;
859 $level0 = $offset;
860 $level0 = getDolGlobalString($used_conf.'0', $level0);
861 $level1 = $offset + $factor;
862 $level1 = getDolGlobalString($used_conf.'1', $level1);
863 $level2 = $offset + 2 * $factor;
864 $level2 = getDolGlobalString($used_conf.'2', $level2);
865 $level3 = $offset + 3 * $factor;
866 $level3 = getDolGlobalString($used_conf.'3', $level3);
867
868 if ($totallate <= $level0) {
869 $weather->picto = 'weather-clear.png';
870 $weather->level = 0;
871 } elseif ($totallate <= $level1) {
872 $weather->picto = 'weather-few-clouds.png';
873 $weather->level = 1;
874 } elseif ($totallate <= $level2) {
875 $weather->picto = 'weather-clouds.png';
876 $weather->level = 2;
877 } elseif ($totallate <= $level3) {
878 $weather->picto = 'weather-many-clouds.png';
879 $weather->level = 3;
880 } else {
881 $weather->picto = 'weather-storm.png';
882 $weather->level = 4;
883 }
884
885 return $weather;
886}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage bank accounts.
Class to manage agenda events (actions)
Class to manage members of a foundation.
Class to manage withdrawal receipts.
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage generation of HTML components Only common components must be here.
static getBoxesArea($user, $areacode)
Get array with HTML tabs with widgets/boxes of a particular area including personalized choices of us...
Class of the module paid holiday.
static saveboxorder($dbs, $zone, $boxorder, $userid=0)
Save order of boxes for area and user.
Class to manage projects.
Class to manage proposals.
Class to manage cheque delivery receipts.
Class to manage price ask supplier.
Class to manage tasks.
img_weather($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $morecss='')
Show weather picto.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles=1, $removeclassattribute=1, $cleanalsojavascript=0, $allowiframe=0, $allowed_tags=array(), $allowlink=0, $allowscript=0, $allowstyle=0, $allowphp=0)
Clean a string to keep only desirable HTML tags.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
showWeather($totallate, $text, $options, $morecss='')
Show weather logo.
Definition index.php:833
getWeatherStatus($totallate)
get weather status for conf 'MAIN_METEO_LEVELx'
Definition index.php:848
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
Class to generate the form for creating a new ticket.