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