dolibarr 21.0.4
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
132/*
133if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
134 $langs->loadLangs(array("admin"));
135 print info_admin($langs->trans("WarningExperimentalFeatureInvoiceSituationNeedToUpgradeToProgressiveMode", 'https://partners.dolibarr.org'));
136 //print "<br>";
137}
138*/
139
140/*
141 * Show security warnings
142 */
143
144// Security warning if install.lock file is missing or if conf file is writable
145if (!getDolGlobalString('MAIN_REMOVE_INSTALL_WARNING')) {
146 $message = '';
147
148 // Check if install lock file is present
149 $lockfile = DOL_DATA_ROOT.'/install.lock';
150 if (!empty($lockfile) && !file_exists($lockfile) && is_dir(DOL_DOCUMENT_ROOT."/install")) {
151 $langs->load("errors");
152 //if (!empty($message)) $message.='<br>';
153 $message .= info_admin($langs->transnoentities("WarningLockFileDoesNotExists", DOL_DATA_ROOT).' '.$langs->transnoentities("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
154 }
155
156 // Conf files must be in read only mode
157 if (is_writable($conffile)) { // $conffile is defined into filefunc.inc.php
158 $langs->load("errors");
159 //$langs->load("other");
160 //if (!empty($message)) $message.='<br>';
161 $message .= info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->transnoentities("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth');
162 }
163
164 $object = new stdClass();
165 $parameters = array();
166 $reshook = $hookmanager->executeHooks('infoadmin', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
167 if ($reshook == 0) {
168 $message .= $hookmanager->resPrint;
169 }
170 if ($message) { // $message is an HTML string.
171 print '<!-- show security warning -->';
172 print dol_string_onlythesehtmltags($message, 1, 0, 0, 0, array('div', 'span', 'b'));
173 //print '<br>';
174 //print info_admin($langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install"));
175 }
176}
177
178/*
179 * Dashboard Dolibarr statistics
180 * Hidden for external users
181 */
182
183print load_fiche_titre('&nbsp;', $resultboxes['selectboxlist'], '', 0, '', 'titleforhome');
184
185// Load translation files required by page
186$langs->loadLangs(array('commercial', 'bills', 'orders', 'contracts'));
187
188// Dolibarr Working Board with weather
189if (!getDolGlobalString('MAIN_DISABLE_GLOBAL_WORKBOARD') && getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
190 $showweather = (!getDolGlobalString('MAIN_DISABLE_METEO') || getDolGlobalInt('MAIN_DISABLE_METEO') == 2) ? 1 : 0;
191
192 // Array that contains all WorkboardResponse classes to process them
193 $dashboardlines = array();
194
195 // Do not include sections without management permission
196 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
197
198 // Number of actions to do (late)
199 if (isModEnabled('agenda') && !getDolGlobalString('MAIN_DISABLE_BLOCK_AGENDA') && $user->hasRight('agenda', 'myactions', 'read')) {
200 include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
201 $board = new ActionComm($db);
202 $dashboardlines[$board->element] = $board->load_board($user);
203 }
204
205 // Number of project opened
206 if (isModEnabled('project') && !getDolGlobalString('MAIN_DISABLE_BLOCK_PROJECT') && $user->hasRight('projet', 'lire')) {
207 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
208 $board = new Project($db);
209 $dashboardlines[$board->element] = $board->load_board($user);
210 }
211
212 // Number of tasks to do (late)
213 if (isModEnabled('project') && !getDolGlobalString('MAIN_DISABLE_BLOCK_PROJECT') && !getDolGlobalString('PROJECT_HIDE_TASKS') && $user->hasRight('projet', 'lire')) {
214 include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
215 $board = new Task($db);
216 $dashboardlines[$board->element] = $board->load_board($user);
217 }
218
219 // Number of commercial customer proposals open (expired)
220 if (isModEnabled('propal') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('propal', 'read')) {
221 include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
222 $board = new Propal($db);
223 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
224 // Number of commercial proposals CLOSED signed (billed)
225 $dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
226 }
227
228 // Number of supplier proposals open (expired)
229 if (isModEnabled('supplier_proposal') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('supplier_proposal', 'lire')) {
230 $langs->load("supplier_proposal");
231 include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
232 $board = new SupplierProposal($db);
233 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
234 // Number of commercial proposals CLOSED signed (billed)
235 $dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed");
236 }
237
238 // Number of sales orders
239 if (isModEnabled('order') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('commande', 'lire')) {
240 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
241 $board = new Commande($db);
242 // Number of customer orders to be shipped (validated and in progress)
243 $dashboardlines[$board->element.'_toship'] = $board->load_board($user, 'toship');
244 // Number of customer orders to be billed (not visible by default, does not match a lot of organization).
245 if (getDolGlobalInt('ORDER_BILL_AFTER_VALIDATION')) {
246 $dashboardlines[$board->element.'_tobill'] = $board->load_board($user, 'tobill');
247 }
248 // Number of customer orders to be billed (delivered but not billed)
249 $dashboardlines[$board->element.'_shippedtobill'] = $board->load_board($user, 'shippedtobill');
250 }
251
252 // Number of suppliers orders
253 if (isModEnabled('supplier_order') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('fournisseur', 'commande', 'lire')) {
254 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
255 $board = new CommandeFournisseur($db);
256 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
257 $dashboardlines[$board->element.'_awaiting'] = $board->load_board($user, 'awaiting');
258 }
259
260 // Number of contract / services enabled (delayed)
261 if (isModEnabled('contract') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CONTRACT') && $user->hasRight('contrat', 'lire')) {
262 include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
263 $board = new Contrat($db);
264 $dashboardlines[$board->element.'_inactive'] = $board->load_board($user, "inactive");
265 // Number of active services (expired)
266 $dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
267 }
268
269 // Number of tickets open
270 if (isModEnabled('ticket') && !getDolGlobalString('MAIN_DISABLE_BLOCK_TICKET') && $user->hasRight('ticket', 'read')) {
271 include_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
272 $board = new Ticket($db);
273 $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened");
274 // Number of active services (expired)
275 //$dashboardlines[$board->element.'_active'] = $board->load_board($user, "active");
276 }
277
278 // Number of invoices customers (paid)
279 if (isModEnabled('invoice') && !getDolGlobalString('MAIN_DISABLE_BLOCK_CUSTOMER') && $user->hasRight('facture', 'lire')) {
280 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
281 $board = new Facture($db);
282 $dashboardlines[$board->element] = $board->load_board($user);
283 }
284
285 // Number of supplier invoices (paid)
286 if (isModEnabled('supplier_invoice') && !getDolGlobalString('MAIN_DISABLE_BLOCK_SUPPLIER') && $user->hasRight('fournisseur', 'facture', 'lire')) {
287 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
288 $board = new FactureFournisseur($db);
289 $dashboardlines[$board->element] = $board->load_board($user);
290 }
291
292 // Number of transactions to conciliate
293 if (isModEnabled('bank') && !getDolGlobalString('MAIN_DISABLE_BLOCK_BANK') && $user->hasRight('banque', 'lire') && !$user->socid) {
294 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
295 $board = new Account($db);
296 $nb = $board->countAccountToReconcile(); // Get nb of account to reconciliate
297 if ($nb > 0) {
298 $dashboardlines[$board->element] = $board->load_board($user);
299 }
300 }
301
302
303 // Number of cheque to send
304 if (isModEnabled('bank') && !getDolGlobalString('MAIN_DISABLE_BLOCK_BANK') && $user->hasRight('banque', 'lire') && !$user->socid) {
305 if (!getDolGlobalString('BANK_DISABLE_CHECK_DEPOSIT')) {
306 include_once DOL_DOCUMENT_ROOT . '/compta/paiement/cheque/class/remisecheque.class.php';
307 $board = new RemiseCheque($db);
308 $dashboardlines[$board->element] = $board->load_board($user);
309 }
310 if (isModEnabled('prelevement')) {
311 include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
312 $board = new BonPrelevement($db);
313 $dashboardlines[$board->element . '_direct_debit'] = $board->load_board($user, 'direct_debit');
314 }
315 if (isModEnabled('paymentbybanktransfer')) {
316 include_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
317 $board = new BonPrelevement($db);
318 $dashboardlines[$board->element . '_credit_transfer'] = $board->load_board($user, 'credit_transfer');
319 }
320 }
321
322 // Number of foundation members
323 if (isModEnabled('member') && !getDolGlobalString('MAIN_DISABLE_BLOCK_ADHERENT') && $user->hasRight('adherent', 'lire') && !$user->socid) {
324 include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
325 $board = new Adherent($db);
326 $dashboardlines[$board->element.'_shift'] = $board->load_board($user, 'shift');
327 $dashboardlines[$board->element.'_expired'] = $board->load_board($user, 'expired');
328 }
329
330 // Number of expense reports to approve
331 if (isModEnabled('expensereport') && !getDolGlobalString('MAIN_DISABLE_BLOCK_EXPENSEREPORT') && $user->hasRight('expensereport', 'approve')) {
332 include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
333 $board = new ExpenseReport($db);
334 $dashboardlines[$board->element.'_toapprove'] = $board->load_board($user, 'toapprove');
335 }
336
337 // Number of expense reports to pay
338 if (isModEnabled('expensereport') && !getDolGlobalString('MAIN_DISABLE_BLOCK_EXPENSEREPORT') && $user->hasRight('expensereport', 'to_paid')) {
339 include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
340 $board = new ExpenseReport($db);
341 $dashboardlines[$board->element.'_topay'] = $board->load_board($user, 'topay');
342 }
343
344 // Number of holidays to approve
345 if (isModEnabled('holiday') && !getDolGlobalString('MAIN_DISABLE_BLOCK_HOLIDAY') && $user->hasRight('holiday', 'approve')) {
346 include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
347 $board = new Holiday($db);
348 $dashboardlines[$board->element] = $board->load_board($user);
349 }
350
351 $object = new stdClass();
352 $parameters = array();
353 $action = '';
354 $reshook = $hookmanager->executeHooks(
355 'addOpenElementsDashboardLine',
356 $parameters,
357 $object,
358 $action
359 ); // Note that $action and $object may have been modified by some hooks
360 if ($reshook == 0) {
361 $dashboardlines = array_merge($dashboardlines, $hookmanager->resArray);
362 }
363
364 /* Open object dashboard */
365 $dashboardgroup = array(
366 'action' =>
367 array(
368 'groupName' => 'Agenda',
369 'stats' => array('action'),
370 ),
371 'project' =>
372 array(
373 'groupName' => 'Projects',
374 'globalStatsKey' => 'projects',
375 'stats' => array('project', 'project_task'),
376 ),
377 'propal' =>
378 array(
379 'groupName' => 'Proposals',
380 'globalStatsKey' => 'proposals',
381 'stats' =>
382 array('propal_opened', 'propal_signed'),
383 ),
384 'commande' =>
385 array(
386 'groupName' => 'Orders',
387 'globalStatsKey' => 'orders',
388 'stats' =>
389 array('commande_toship', 'commande_tobill', 'commande_shippedtobill'),
390 ),
391 'facture' =>
392 array(
393 'groupName' => 'Invoices',
394 'globalStatsKey' => 'invoices',
395 'stats' =>
396 array('facture'),
397 ),
398 'supplier_proposal' =>
399 array(
400 'lang' => 'supplier_proposal',
401 'groupName' => 'SupplierProposals',
402 'globalStatsKey' => 'askprice',
403 'stats' =>
404 array('supplier_proposal_opened', 'supplier_proposal_signed'),
405 ),
406 'order_supplier' =>
407 array(
408 'groupName' => 'SuppliersOrders',
409 'globalStatsKey' => 'supplier_orders',
410 'stats' =>
411 array('order_supplier_opened', 'order_supplier_awaiting'),
412 ),
413 'invoice_supplier' =>
414 array(
415 'groupName' => 'BillsSuppliers',
416 'globalStatsKey' => 'supplier_invoices',
417 'stats' =>
418 array('invoice_supplier'),
419 ),
420 'contrat' =>
421 array(
422 'groupName' => 'Contracts',
423 'globalStatsKey' => 'Contracts',
424 'stats' =>
425 array('contrat_inactive', 'contrat_active'),
426 ),
427 'ticket' =>
428 array(
429 'groupName' => 'Tickets',
430 'globalStatsKey' => 'ticket',
431 'stats' =>
432 array('ticket_opened'),
433 ),
434 'bank_account' =>
435 array(
436 'groupName' => 'BankAccount',
437 'stats' =>
438 array('bank_account', 'chequereceipt', 'widthdraw_direct_debit', 'widthdraw_credit_transfer'),
439 ),
440 'member' =>
441 array(
442 'groupName' => 'Members',
443 'globalStatsKey' => 'members',
444 'stats' =>
445 array('member_shift', 'member_expired'),
446 ),
447 'expensereport' =>
448 array(
449 'groupName' => 'ExpenseReport',
450 'globalStatsKey' => 'expensereports',
451 'stats' =>
452 array('expensereport_toapprove', 'expensereport_topay'),
453 ),
454 'holiday' =>
455 array(
456 'groupName' => 'Holidays',
457 'globalStatsKey' => 'holidays',
458 'stats' =>
459 array('holiday'),
460 ),
461 );
462
463 $object = new stdClass();
464 $parameters = array(
465 'dashboardgroup' => $dashboardgroup
466 );
467 $reshook = $hookmanager->executeHooks('addOpenElementsDashboardGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
468 if ($reshook == 0) {
469 $dashboardgroup = array_merge($dashboardgroup, $hookmanager->resArray);
470 }
471
472
473 // Calculate total nb of late
474 $totallate = $totaltodo = 0;
475
476 //Remove any invalid response
477 //load_board can return an integer if failed, or WorkboardResponse if OK
478 $valid_dashboardlines = array();
479 foreach ($dashboardlines as $workboardid => $tmp) {
480 if ($tmp instanceof WorkboardResponse) {
481 $tmp->id = $workboardid; // Complete the object to add its id into its name
482 $valid_dashboardlines[$workboardid] = $tmp;
483 }
484 }
485
486 // We calculate $totallate. Must be defined before start of next loop because it is show in first fetch on next loop
487 foreach ($valid_dashboardlines as $board) {
488 if (is_numeric($board->nbtodo) && is_numeric($board->nbtodolate) && $board->nbtodolate > 0) {
489 $totaltodo += $board->nbtodo;
490 $totallate += $board->nbtodolate;
491 }
492 }
493
494 $openedDashBoardSize = 'info-box-sm'; // use sm by default
495 foreach ($dashboardgroup as $dashbordelement) {
496 if (is_array($dashbordelement['stats']) && count($dashbordelement['stats']) > 2) {
497 $openedDashBoardSize = ''; // use default info box size : big
498 break;
499 }
500 }
501
502 $totalLateNumber = $totallate;
503 $totallatePercentage = ((!empty($totaltodo)) ? round($totallate / $totaltodo * 100, 2) : 0);
504 if (getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE')) {
505 $totallate = $totallatePercentage;
506 }
507
508 // 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.
509 $boxwork = '';
510 $boxwork .= '<div class="box">';
511 $boxwork .= '<table summary="'.dol_escape_htmltag($langs->trans("WorkingBoard")).'" class="noborder boxtable boxtablenobottom boxworkingboard centpercent">'."\n";
512 $boxwork .= '<tr class="liste_titre">';
513 $boxwork .= '<th class="liste_titre"><div class="inline-block valignmiddle">'.$langs->trans("DolibarrWorkBoard").'</div>';
514 if ($showweather) {
515 if ($totallate > 0) {
516 $text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv(
517 "NActionsLate",
518 $totallate.(getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? '%' : '')
519 ).')';
520 } else {
521 $text = $langs->transnoentitiesnoconv("NoItemLate");
522 }
523 $text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
524 //$text.=$form->textwithpicto('',$langs->trans("LateDesc"));
525 $options = 'height="24px" style="float: right"';
526 $boxwork .= showWeather($totallate, $text, $options, 'inline-block valignmiddle');
527 }
528 $boxwork .= '</th>';
529 $boxwork .= '</tr>'."\n";
530
531 // Show dashboard
532 $nbworkboardempty = 0;
533 $isIntopOpenedDashBoard = $globalStatInTopOpenedDashBoard = array();
534 $openedDashBoard = '';
535 if (!empty($valid_dashboardlines)) {
536 $boxwork .= '<tr class="nobottom nohover"><td class="tdboxstats nohover flexcontainer centpercent"><div style="display: flex: flex-wrap: wrap">';
537
538 foreach ($dashboardgroup as $groupKey => $groupElement) {
539 $boards = array();
540
541 // Scan $groupElement and save the one with 'stats' that must be used for the open objects dashboard
542 if (!getDolGlobalString('MAIN_DISABLE_NEW_OPENED_DASH_BOARD')) {
543 foreach ($groupElement['stats'] as $infoKey) {
544 if (!empty($valid_dashboardlines[$infoKey])) {
545 $boards[] = $valid_dashboardlines[$infoKey];
546 $isIntopOpenedDashBoard[] = $infoKey;
547 }
548 }
549 }
550
551 if (!empty($boards)) {
552 if (!empty($groupElement['lang'])) {
553 $langs->load($groupElement['lang']);
554 }
555 // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset
556 $groupName = $langs->trans($groupElement['groupName']);
557 $groupKeyLowerCase = strtolower($groupKey);
558
559 // global stats
560 $globalStatsKey = false;
561 if (!empty($groupElement['globalStatsKey']) && empty($groupElement['globalStats'])) { // can be filled by hook
562 $globalStatsKey = $groupElement['globalStatsKey'];
563 $groupElement['globalStats'] = array();
564 }
565
566 $openedDashBoard .= '<div class="box-flex-item"><div class="box-flex-item-with-margin">'."\n";
567 $openedDashBoard .= ' <div class="info-box '.$openedDashBoardSize.'">'."\n";
568 $openedDashBoard .= ' <span class="info-box-icon bg-infobox-'.$groupKeyLowerCase.'">'."\n";
569 $openedDashBoard .= ' <i class="fa fa-dol-'.$groupKeyLowerCase.'"></i>'."\n";
570
571 // Show the span for the total of record. TODO This seems not used.
572 if (!empty($groupElement['globalStats'])) {
573 $globalStatInTopOpenedDashBoard[] = $globalStatsKey;
574 $openedDashBoard .= '<span class="info-box-icon-text" title="'.$groupElement['globalStats']['text'].'">'.$groupElement['globalStats']['nbTotal'].'</span>';
575 }
576
577 $openedDashBoard .= '</span>'."\n";
578 $openedDashBoard .= '<div class="info-box-content">'."\n";
579
580 $openedDashBoard .= '<div class="info-box-title" title="'.dolPrintHTMLForAttribute($groupName).'">'.$groupName.'</div>'."\n";
581 $openedDashBoard .= '<div class="info-box-lines">'."\n";
582
583 foreach ($boards as $board) {
584 $openedDashBoard .= '<div class="info-box-line spanoverflow nowrap">';
585
586 if (!empty($board->labelShort)) {
587 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text" title="'.$board->label.'">'.$board->labelShort.'</div>';
588 } else {
589 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text">'.$board->label.'</div>';
590 }
591
592 $textLateTitle = $langs->trans("NActionsLate", $board->nbtodolate);
593 $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").')';
594
595 if ($board->id == 'bank_account') {
596 $textLateTitle .= '<br><span class="opacitymedium">'.$langs->trans("IfYouDontReconcileDisableProperty", $langs->transnoentitiesnoconv("Conciliable")).'</span>';
597 }
598
599 $textLate = '';
600 if ($board->nbtodolate > 0) {
601 $textLate .= '<span title="'.dol_escape_htmltag($textLateTitle).'" class="classfortooltip badge badge-warning">';
602 $textLate .= '<i class="fa fa-exclamation-triangle hideonsmartphone"></i> '.$board->nbtodolate;
603 $textLate .= '</span>';
604 }
605
606 $nbtodClass = '';
607 if ($board->nbtodo > 0) {
608 $nbtodClass = 'badge badge-info';
609 } else {
610 $nbtodClass = 'opacitymedium';
611 }
612
613 // Forge the line to show into the open object box
614 $labeltoshow = $board->label.' ('.$board->nbtodo.')';
615 if ($board->total > 0) {
616 $labeltoshow .= ' - '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
617 }
618 $openedDashBoard .= '<a href="'.$board->url.'" class="info-box-text info-box-text-a">';
619 $openedDashBoard .= $infoName;
620 $openedDashBoard .= '<div class="inline-block nowraponall">';
621 $openedDashBoard .= '<span class="classfortooltip'.($nbtodClass ? ' '.$nbtodClass : '').'" title="'.$labeltoshow.'">';
622 $openedDashBoard .= $board->nbtodo;
623 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
624 $openedDashBoard .= ' : '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
625 }
626 $openedDashBoard .= '</span>';
627
628 if ($textLate) {
629 if ($board->url_late) {
630 $openedDashBoard .= '</div></a>';
631 $openedDashBoard .= ' <div class="inline-block"><a href="'.$board->url_late.'" class="info-box-text info-box-text-a paddingleft">';
632 } else {
633 $openedDashBoard .= ' ';
634 }
635 $openedDashBoard .= $textLate;
636 }
637 $openedDashBoard .= '</a>'."\n";
638 $openedDashBoard .= '</div>';
639 $openedDashBoard .= '</div>'."\n";
640 }
641
642 // TODO Add hook here to add more "info-box-line"
643
644 $openedDashBoard .= ' </div><!-- /.info-box-lines --></div><!-- /.info-box-content -->'."\n";
645 $openedDashBoard .= ' </div><!-- /.info-box -->'."\n";
646 $openedDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
647 $openedDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
648 $openedDashBoard .= "\n";
649 }
650 }
651
652 if ($showweather && !empty($isIntopOpenedDashBoard)) {
653 $appendClass = (getDolGlobalInt('MAIN_DISABLE_METEO') == 2 ? ' hideonsmartphone' : '');
654 $weather = getWeatherStatus($totallate);
655
656 $text = '';
657 if ($totallate > 0) {
658 $text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv(
659 "NActionsLate",
660 $totallate.(getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? '%' : '')
661 ).')';
662 } else {
663 $text = $langs->transnoentitiesnoconv("NoItemLate");
664 }
665 $text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
666
667 $weatherDashBoard = '<div class="box-flex-item '.$appendClass.'"><div class="box-flex-item-with-margin">'."\n";
668 $weatherDashBoard .= ' <div class="info-box '.$openedDashBoardSize.' info-box-weather info-box-weather-level'.$weather->level.'">'."\n";
669 $weatherDashBoard .= ' <span class="info-box-icon">';
670 $weatherDashBoard .= img_weather('', $weather->level, '', 0, 'valignmiddle width50');
671 $weatherDashBoard .= ' </span>'."\n";
672 $weatherDashBoard .= ' <div class="info-box-content">'."\n";
673 $weatherDashBoard .= ' <div class="info-box-title">'.$langs->trans('GlobalOpenedElemView').'</div>'."\n";
674
675 if ($totallatePercentage > 0 && getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE')) {
676 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
677 "NActionsLate",
678 price($totallatePercentage).'%'
679 ).'</span>'."\n";
680 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
681 'NActionsLate',
682 $totalLateNumber
683 ).'</span>'."\n";
684 } else {
685 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
686 "NActionsLate",
687 $totalLateNumber
688 ).'</span>'."\n";
689 if ($totallatePercentage > 0) {
690 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
691 'NActionsLate',
692 price($totallatePercentage).'%'
693 ).'</span>'."\n";
694 }
695 }
696
697 $weatherDashBoard .= ' </div><!-- /.info-box-content -->'."\n";
698 $weatherDashBoard .= ' </div><!-- /.info-box -->'."\n";
699 $weatherDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
700 $weatherDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
701 $weatherDashBoard .= "\n";
702
703 $openedDashBoard = $weatherDashBoard.$openedDashBoard;
704 }
705
706 if (!empty($isIntopOpenedDashBoard)) {
707 for ($i = 1; $i <= 10; $i++) {
708 $openedDashBoard .= '<div class="box-flex-item filler"></div>';
709 }
710 }
711
712 $nbworkboardcount = 0;
713 foreach ($valid_dashboardlines as $infoKey => $board) {
714 if (in_array($infoKey, $isIntopOpenedDashBoard)) {
715 // skip if info is present on top
716 continue;
717 }
718
719 if (empty($board->nbtodo)) {
720 $nbworkboardempty++;
721 }
722 $nbworkboardcount++;
723
724
725 $textlate = $langs->trans("NActionsLate", $board->nbtodolate);
726 $textlate .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')';
727
728
729 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats130 boxstatsborder">';
730 $boxwork .= '<div class="boxstatscontent">';
731 $boxwork .= '<span class="boxstatstext" title="'.dol_escape_htmltag($board->label).'">'.$board->img.' <span>'.$board->label.'</span></span><br>';
732 $boxwork .= '<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.$board->nbtodo.'</span></a>';
733 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
734 $boxwork .= '&nbsp;/&nbsp;<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.price($board->total).'</span></a>';
735 }
736 $boxwork .= '</div>';
737 if ($board->nbtodolate > 0) {
738 $boxwork .= '<div class="dashboardlinelatecoin nowrap">';
739 $boxwork .= '<a title="'.dol_escape_htmltag($textlate).'" class="valignmiddle dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'" href="'.((!$board->url_late) ? $board->url : $board->url_late).'">';
740 //$boxwork .= img_picto($textlate, "warning_white", 'class="valigntextbottom"');
741 $boxwork .= img_picto(
742 $textlate,
743 "warning_white",
744 'class="inline-block hideonsmartphone valigntextbottom"'
745 );
746 $boxwork .= '<span class="dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'">';
747 $boxwork .= $board->nbtodolate;
748 $boxwork .= '</span>';
749 $boxwork .= '</a>';
750 $boxwork .= '</div>';
751 }
752 $boxwork .= '</div></div>';
753 $boxwork .= "\n";
754 }
755
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 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
759 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
760
761 $boxwork .= '</div>';
762 $boxwork .= '</td></tr>';
763 } else {
764 $boxwork .= '<tr class="nohover">';
765 $boxwork .= '<td class="nohover valignmiddle opacitymedium">';
766 $boxwork .= $langs->trans("NoOpenedElementToProcess");
767 $boxwork .= '</td>';
768 $boxwork .= '</tr>';
769 }
770
771 $boxwork .= '</td></tr>';
772
773 $boxwork .= '</table>'; // End table array of working board
774 $boxwork .= '</div>';
775
776 if (!empty($isIntopOpenedDashBoard)) {
777 print '<div class="fichecenter">';
778 print '<div class="opened-dash-board-wrap"><div class="box-flex-container">'.$openedDashBoard.'</div></div>';
779 print '</div>';
780 }
781}
782
783
784print '<div class="clearboth"></div>';
785
786print '<div class="fichecenter fichecenterbis">';
787
788
789/*
790 * Show widgets (boxes)
791 */
792
793$boxlist = '<div class="twocolumns">';
794
795$boxlist .= '<div class="firstcolumn fichehalfleft boxhalfleft" id="boxhalfleft">';
796if (!empty($nbworkboardcount)) {
797 $boxlist .= $boxwork;
798}
799
800$boxlist .= $resultboxes['boxlista'];
801
802$boxlist .= '</div>';
803
804$boxlist .= '<div class="secondcolumn fichehalfright boxhalfright" id="boxhalfright">';
805
806$boxlist .= $resultboxes['boxlistb'];
807
808$boxlist .= '</div>';
809$boxlist .= "\n";
810
811$boxlist .= '</div>';
812
813
814print $boxlist;
815
816print '</div>';
817
818//print 'mem='.memory_get_usage().' - '.memory_get_peak_usage();
819
820// End of page
821llxFooter();
822$db->close();
823
824
835function showWeather($totallate, $text, $options, $morecss = '')
836{
837 global $conf;
838
839 $weather = getWeatherStatus($totallate);
840 return img_weather($text, $weather->picto, $options, 0, $morecss);
841}
842
843
850function getWeatherStatus($totallate)
851{
852 $weather = new stdClass();
853 $weather->picto = '';
854
855 $offset = 0;
856 $factor = 10; // By default
857
858 $used_conf = (getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL');
859
860 $weather->level = 0;
861 $level0 = $offset;
862 $level0 = getDolGlobalString($used_conf.'0', $level0);
863 $level1 = $offset + $factor;
864 $level1 = getDolGlobalString($used_conf.'1', $level1);
865 $level2 = $offset + 2 * $factor;
866 $level2 = getDolGlobalString($used_conf.'2', $level2);
867 $level3 = $offset + 3 * $factor;
868 $level3 = getDolGlobalString($used_conf.'3', $level3);
869
870 if ($totallate <= $level0) {
871 $weather->picto = 'weather-clear.png';
872 $weather->level = 0;
873 } elseif ($totallate <= $level1) {
874 $weather->picto = 'weather-few-clouds.png';
875 $weather->level = 1;
876 } elseif ($totallate <= $level2) {
877 $weather->picto = 'weather-clouds.png';
878 $weather->level = 2;
879 } elseif ($totallate <= $level3) {
880 $weather->picto = 'weather-many-clouds.png';
881 $weather->level = 3;
882 } else {
883 $weather->picto = 'weather-storm.png';
884 $weather->level = 4;
885 }
886
887 return $weather;
888}
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:835
getWeatherStatus($totallate)
get weather status for conf 'MAIN_METEO_LEVELx'
Definition index.php:850
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.