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