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-2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
31define('CSRFCHECK_WITH_TOKEN', 1); // We force need to use a token to login when making a POST
32
33require 'main.inc.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
35
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 $openedDashBoard = '';
520 if (!empty($valid_dashboardlines)) {
521 $boxwork .= '<tr class="nobottom nohover"><td class="tdboxstats nohover flexcontainer centpercent"><div style="display: flex: flex-wrap: wrap">';
522
523 foreach ($dashboardgroup as $groupKey => $groupElement) {
524 $boards = array();
525
526 // Scan $groupElement and save the one with 'stats' that must be used for the open objects dashboard
527 if (!getDolGlobalString('MAIN_DISABLE_NEW_OPENED_DASH_BOARD')) {
528 foreach ($groupElement['stats'] as $infoKey) {
529 if (!empty($valid_dashboardlines[$infoKey])) {
530 $boards[] = $valid_dashboardlines[$infoKey];
531 $isIntopOpenedDashBoard[] = $infoKey;
532 }
533 }
534 }
535
536 if (!empty($boards)) {
537 if (!empty($groupElement['lang'])) {
538 $langs->load($groupElement['lang']);
539 }
540 // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset
541 $groupName = $langs->trans($groupElement['groupName']);
542 $groupKeyLowerCase = strtolower($groupKey);
543
544 // global stats
545 $globalStatsKey = false;
546 if (!empty($groupElement['globalStatsKey']) && empty($groupElement['globalStats'])) { // can be filled by hook
547 $globalStatsKey = $groupElement['globalStatsKey'];
548 $groupElement['globalStats'] = array();
549 }
550
551 $openedDashBoard .= '<div class="box-flex-item"><div class="box-flex-item-with-margin">'."\n";
552 $openedDashBoard .= ' <div class="info-box '.$openedDashBoardSize.'">'."\n";
553 $openedDashBoard .= ' <span class="info-box-icon bg-infobox-'.$groupKeyLowerCase.'">'."\n";
554 $openedDashBoard .= ' <i class="fa fa-dol-'.$groupKeyLowerCase.'"></i>'."\n";
555
556 // Show the span for the total of record. TODO This seems not used.
557 if (!empty($groupElement['globalStats'])) {
558 $globalStatInTopOpenedDashBoard[] = $globalStatsKey;
559 $openedDashBoard .= '<span class="info-box-icon-text" title="'.$groupElement['globalStats']['text'].'">'.$groupElement['globalStats']['nbTotal'].'</span>';
560 }
561
562 $openedDashBoard .= '</span>'."\n";
563 $openedDashBoard .= '<div class="info-box-content">'."\n";
564
565 $openedDashBoard .= '<div class="info-box-title" title="'.strip_tags($groupName).'">'.$groupName.'</div>'."\n";
566 $openedDashBoard .= '<div class="info-box-lines">'."\n";
567
568 foreach ($boards as $board) {
569 $openedDashBoard .= '<div class="info-box-line spanoverflow nowrap">';
570
571 if (!empty($board->labelShort)) {
572 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text" title="'.$board->label.'">'.$board->labelShort.'</div>';
573 } else {
574 $infoName = '<div class="marginrightonly inline-block valignmiddle info-box-line-text">'.$board->label.'</div>';
575 }
576
577 $textLateTitle = $langs->trans("NActionsLate", $board->nbtodolate);
578 $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").')';
579
580 if ($board->id == 'bank_account') {
581 $textLateTitle .= '<br><span class="opacitymedium">'.$langs->trans("IfYouDontReconcileDisableProperty", $langs->transnoentitiesnoconv("Conciliable")).'</span>';
582 }
583
584 $textLate = '';
585 if ($board->nbtodolate > 0) {
586 $textLate .= '<span title="'.dol_escape_htmltag($textLateTitle).'" class="classfortooltip badge badge-warning">';
587 $textLate .= '<i class="fa fa-exclamation-triangle"></i> '.$board->nbtodolate;
588 $textLate .= '</span>';
589 }
590
591 $nbtodClass = '';
592 if ($board->nbtodo > 0) {
593 $nbtodClass = 'badge badge-info';
594 } else {
595 $nbtodClass = 'opacitymedium';
596 }
597
598 // Forge the line to show into the open object box
599 $labeltoshow = $board->label.' ('.$board->nbtodo.')';
600 if ($board->total > 0) {
601 $labeltoshow .= ' - '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
602 }
603 $openedDashBoard .= '<a href="'.$board->url.'" class="info-box-text info-box-text-a">';
604 $openedDashBoard .= $infoName;
605 $openedDashBoard .= '<div class="inline-block nowraponall">';
606 $openedDashBoard .= '<span class="classfortooltip'.($nbtodClass ? ' '.$nbtodClass : '').'" title="'.$labeltoshow.'">';
607 $openedDashBoard .= $board->nbtodo;
608 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
609 $openedDashBoard .= ' : '.price($board->total, 0, $langs, 1, -1, -1, $conf->currency);
610 }
611 $openedDashBoard .= '</span>';
612
613 if ($textLate) {
614 if ($board->url_late) {
615 $openedDashBoard .= '</div></a>';
616 $openedDashBoard .= ' <div class="inline-block"><a href="'.$board->url_late.'" class="info-box-text info-box-text-a paddingleft">';
617 } else {
618 $openedDashBoard .= ' ';
619 }
620 $openedDashBoard .= $textLate;
621 }
622 $openedDashBoard .= '</a>'."\n";
623 $openedDashBoard .= '</div>';
624 $openedDashBoard .= '</div>'."\n";
625 }
626
627 // TODO Add hook here to add more "info-box-line"
628
629 $openedDashBoard .= ' </div><!-- /.info-box-lines --></div><!-- /.info-box-content -->'."\n";
630 $openedDashBoard .= ' </div><!-- /.info-box -->'."\n";
631 $openedDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
632 $openedDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
633 $openedDashBoard .= "\n";
634 }
635 }
636
637 if ($showweather && !empty($isIntopOpenedDashBoard)) {
638 $appendClass = (getDolGlobalInt('MAIN_DISABLE_METEO') == 2 ? ' hideonsmartphone' : '');
639 $weather = getWeatherStatus($totallate);
640
641 $text = '';
642 if ($totallate > 0) {
643 $text = $langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv(
644 "NActionsLate",
645 $totallate.(getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? '%' : '')
646 ).')';
647 } else {
648 $text = $langs->transnoentitiesnoconv("NoItemLate");
649 }
650 $text .= '. '.$langs->transnoentitiesnoconv("LateDesc");
651
652 $weatherDashBoard = '<div class="box-flex-item '.$appendClass.'"><div class="box-flex-item-with-margin">'."\n";
653 $weatherDashBoard .= ' <div class="info-box '.$openedDashBoardSize.' info-box-weather info-box-weather-level'.$weather->level.'">'."\n";
654 $weatherDashBoard .= ' <span class="info-box-icon">';
655 $weatherDashBoard .= img_weather('', $weather->level, '', 0, 'valignmiddle width50');
656 $weatherDashBoard .= ' </span>'."\n";
657 $weatherDashBoard .= ' <div class="info-box-content">'."\n";
658 $weatherDashBoard .= ' <div class="info-box-title">'.$langs->trans('GlobalOpenedElemView').'</div>'."\n";
659
660 if ($totallatePercentage > 0 && getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE')) {
661 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
662 "NActionsLate",
663 price($totallatePercentage).'%'
664 ).'</span>'."\n";
665 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
666 'NActionsLate',
667 $totalLateNumber
668 ).'</span>'."\n";
669 } else {
670 $weatherDashBoard .= ' <span class="info-box-number">'.$langs->transnoentitiesnoconv(
671 "NActionsLate",
672 $totalLateNumber
673 ).'</span>'."\n";
674 if ($totallatePercentage > 0) {
675 $weatherDashBoard .= ' <span class="progress-description">'.$langs->trans(
676 'NActionsLate',
677 price($totallatePercentage).'%'
678 ).'</span>'."\n";
679 }
680 }
681
682 $weatherDashBoard .= ' </div><!-- /.info-box-content -->'."\n";
683 $weatherDashBoard .= ' </div><!-- /.info-box -->'."\n";
684 $weatherDashBoard .= '</div><!-- /.box-flex-item-with-margin -->'."\n";
685 $weatherDashBoard .= '</div><!-- /.box-flex-item -->'."\n";
686 $weatherDashBoard .= "\n";
687
688 $openedDashBoard = $weatherDashBoard.$openedDashBoard;
689 }
690
691 if (!empty($isIntopOpenedDashBoard)) {
692 for ($i = 1; $i <= 10; $i++) {
693 $openedDashBoard .= '<div class="box-flex-item filler"></div>';
694 }
695 }
696
697 $nbworkboardcount = 0;
698 foreach ($valid_dashboardlines as $infoKey => $board) {
699 if (in_array($infoKey, $isIntopOpenedDashBoard)) {
700 // skip if info is present on top
701 continue;
702 }
703
704 if (empty($board->nbtodo)) {
705 $nbworkboardempty++;
706 }
707 $nbworkboardcount++;
708
709
710 $textlate = $langs->trans("NActionsLate", $board->nbtodolate);
711 $textlate .= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')';
712
713
714 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats130 boxstatsborder">';
715 $boxwork .= '<div class="boxstatscontent">';
716 $boxwork .= '<span class="boxstatstext" title="'.dol_escape_htmltag($board->label).'">'.$board->img.' <span>'.$board->label.'</span></span><br>';
717 $boxwork .= '<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.$board->nbtodo.'</span></a>';
718 if ($board->total > 0 && getDolGlobalString('MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX')) {
719 $boxwork .= '&nbsp;/&nbsp;<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0) ? ' dashboardlineok' : '').'">'.price($board->total).'</span></a>';
720 }
721 $boxwork .= '</div>';
722 if ($board->nbtodolate > 0) {
723 $boxwork .= '<div class="dashboardlinelatecoin nowrap">';
724 $boxwork .= '<a title="'.dol_escape_htmltag($textlate).'" class="valignmiddle dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'" href="'.((!$board->url_late) ? $board->url : $board->url_late).'">';
725 //$boxwork .= img_picto($textlate, "warning_white", 'class="valigntextbottom"');
726 $boxwork .= img_picto(
727 $textlate,
728 "warning_white",
729 'class="inline-block hideonsmartphone valigntextbottom"'
730 );
731 $boxwork .= '<span class="dashboardlineindicatorlate'.($board->nbtodolate > 0 ? ' dashboardlineko' : ' dashboardlineok').'">';
732 $boxwork .= $board->nbtodolate;
733 $boxwork .= '</span>';
734 $boxwork .= '</a>';
735 $boxwork .= '</div>';
736 }
737 $boxwork .= '</div></div>';
738 $boxwork .= "\n";
739 }
740
741 $boxwork .= '<div class="boxstatsindicator thumbstat150 nobold nounderline"><div class="boxstats150empty"></div></div>';
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
746 $boxwork .= '</div>';
747 $boxwork .= '</td></tr>';
748 } else {
749 $boxwork .= '<tr class="nohover">';
750 $boxwork .= '<td class="nohover valignmiddle opacitymedium">';
751 $boxwork .= $langs->trans("NoOpenedElementToProcess");
752 $boxwork .= '</td>';
753 $boxwork .= '</tr>';
754 }
755
756 $boxwork .= '</td></tr>';
757
758 $boxwork .= '</table>'; // End table array of working board
759 $boxwork .= '</div>';
760
761 if (!empty($isIntopOpenedDashBoard)) {
762 print '<div class="fichecenter">';
763 print '<div class="opened-dash-board-wrap"><div class="box-flex-container">'.$openedDashBoard.'</div></div>';
764 print '</div>';
765 }
766}
767
768
769print '<div class="clearboth"></div>';
770
771print '<div class="fichecenter fichecenterbis">';
772
773
774/*
775 * Show widgets (boxes)
776 */
777
778$boxlist = '<div class="twocolumns">';
779
780$boxlist .= '<div class="firstcolumn fichehalfleft boxhalfleft" id="boxhalfleft">';
781if (!empty($nbworkboardcount)) {
782 $boxlist .= $boxwork;
783}
784
785$boxlist .= $resultboxes['boxlista'];
786
787$boxlist .= '</div>';
788
789$boxlist .= '<div class="secondcolumn fichehalfright boxhalfright" id="boxhalfright">';
790
791$boxlist .= $resultboxes['boxlistb'];
792
793$boxlist .= '</div>';
794$boxlist .= "\n";
795
796$boxlist .= '</div>';
797
798
799print $boxlist;
800
801print '</div>';
802
803//print 'mem='.memory_get_usage().' - '.memory_get_peak_usage();
804
805// End of page
806llxFooter();
807$db->close();
808
809
820function showWeather($totallate, $text, $options, $morecss = '')
821{
822 global $conf;
823
824 $weather = getWeatherStatus($totallate);
825 return img_weather($text, $weather->picto, $options, 0, $morecss);
826}
827
828
835function getWeatherStatus($totallate)
836{
837 $weather = new stdClass();
838 $weather->picto = '';
839
840 $offset = 0;
841 $factor = 10; // By default
842
843 $used_conf = (getDolGlobalString('MAIN_USE_METEO_WITH_PERCENTAGE') ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL');
844
845 $weather->level = 0;
846 $level0 = $offset;
847 $level0 = getDolGlobalString($used_conf.'0', $level0);
848 $level1 = $offset + $factor;
849 $level1 = getDolGlobalString($used_conf.'1', $level1);
850 $level2 = $offset + 2 * $factor;
851 $level2 = getDolGlobalString($used_conf.'2', $level2);
852 $level3 = $offset + 3 * $factor;
853 $level3 = getDolGlobalString($used_conf.'3', $level3);
854
855 if ($totallate <= $level0) {
856 $weather->picto = 'weather-clear.png';
857 $weather->level = 0;
858 } elseif ($totallate <= $level1) {
859 $weather->picto = 'weather-few-clouds.png';
860 $weather->level = 1;
861 } elseif ($totallate <= $level2) {
862 $weather->picto = 'weather-clouds.png';
863 $weather->level = 2;
864 } elseif ($totallate <= $level3) {
865 $weather->picto = 'weather-many-clouds.png';
866 $weather->level = 3;
867 } else {
868 $weather->picto = 'weather-storm.png';
869 $weather->level = 4;
870 }
871
872 return $weather;
873}
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, $allowstyle=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:820
getWeatherStatus($totallate)
get weather status for conf 'MAIN_METEO_LEVELx'
Definition index.php:835
Class to generate the form for creating a new ticket.