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