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