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