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