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