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 }
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:40
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
img_weather($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $morecss='')
Show weather picto.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
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 dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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 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:799
getWeatherStatus($totallate)
get weather level $conf->global->MAIN_METEO_LEVELx
Definition: index.php:815
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
Class to generate the form for creating a new ticket.
llxFooter()
Footer empty.
Definition: index.php:71
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