dolibarr  19.0.0-dev
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (c) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
6  * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
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 // Load Dolibarr environment
30 require '../../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
37 
38 $WIDTH = DolGraph::getDefaultGraphSizeForStats('width', 380);
39 $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height', 160);
40 
41 // Load translation files required by the page
42 $langs->loadLangs(array('companies', 'products', 'stocks', 'bills', 'other'));
43 
44 $id = GETPOST('id', 'int'); // For this page, id can also be 'all'
45 $ref = GETPOST('ref', 'alpha');
46 $mode = (GETPOST('mode', 'alpha') ? GETPOST('mode', 'alpha') : 'byunit');
47 $search_year = GETPOST('search_year', 'int');
48 $search_categ = GETPOST('search_categ', 'int');
49 $notab = GETPOST('notab', 'int');
50 $type = GETPOST('type', 'alpha');
51 
52 $error = 0;
53 $mesg = '';
54 $graphfiles = array();
55 
56 $socid = GETPOST('socid', 'int');
57 if (!empty($user->socid)) {
58  $socid = $user->socid;
59 }
60 if ($socid < 0) {
61  $socid = 0;
62 }
63 
64 // Security check
65 $fieldvalue = ($id > 0 ? $id : $ref);
66 $fieldtype = (!empty($ref) ? 'ref' : 'rowid');
67 
68 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
69 $hookmanager->initHooks(array('productstatscard', 'globalcard'));
70 
71 $tmp = dol_getdate(dol_now());
72 $currentyear = $tmp['year'];
73 if (empty($search_year)) {
74  $search_year = $currentyear;
75 }
76 $moreforfilter = "";
77 
78 $object = new Product($db);
79 if ($id > 0 || !empty($ref)) {
80  $result = $object->fetch($id, $ref);
81 }
82 
83 $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype);
84 
85 
86 /*
87  * Actions
88  */
89 
90 // None
91 
92 
93 /*
94  * View
95  */
96 
97 $form = new Form($db);
98 $htmlother = new FormOther($db);
99 
100 if (!($id > 0) && empty($ref) || $notab) {
101  $notab = 1;
102 
103  llxHeader("", $langs->trans("ProductStatistics"));
104 
105  $type = GETPOST('type', 'int');
106 
107  $helpurl = '';
108  if ($type == '0') {
109  $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
110  //$title=$langs->trans("StatisticsOfProducts");
111  $title = $langs->trans("Statistics");
112  } elseif ($type == '1') {
113  $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
114  //$title=$langs->trans("StatisticsOfServices");
115  $title = $langs->trans("Statistics");
116  } else {
117  $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
118  //$title=$langs->trans("StatisticsOfProductsOrServices");
119  $title = $langs->trans("Statistics");
120  }
121 
122  $picto = 'product';
123  if ($type == 1) {
124  $picto = 'service';
125  }
126 
127  print load_fiche_titre($title, $mesg, $picto);
128 } else {
129  $result = $object->fetch($id, $ref);
130 
131  $title = $langs->trans('ProductServiceCard');
132  $helpurl = '';
133  $shortlabel = dol_trunc($object->label, 16);
134  if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
135  $title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('Statistics');
136  $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
137  }
138  if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
139  $title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('Statistics');
140  $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
141  }
142 
143  llxHeader('', $title, $helpurl);
144 }
145 
146 
147 if ($result && ($id > 0 || !empty($ref)) && empty($notab)) {
148  $head = product_prepare_head($object);
149  $titre = $langs->trans("CardProduct".$object->type);
150  $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product');
151 
152  print dol_get_fiche_head($head, 'stats', $titre, -1, $picto);
153 
154  $linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
155 
156  dol_banner_tab($object, 'ref', $linkback, ($user->socid ? 0 : 1), 'ref', '', '', '', 0, '', '', 1);
157 
158  print dol_get_fiche_end();
159 }
160 if ((!($id > 0) && empty($ref)) || $notab) {
161  $h = 0;
162  $head = array();
163 
164  $head[$h][0] = DOL_URL_ROOT.'/product/stats/card.php'.($type != '' ? '?type='.((int) $type) : '');
165  $head[$h][1] = $langs->trans("Chart");
166  $head[$h][2] = 'chart';
167  $h++;
168 
169  $title = $langs->trans("ListProductServiceByPopularity");
170  if ((string) $type == '1') {
171  $title = $langs->trans("ListServiceByPopularity");
172  }
173  if ((string) $type == '0') {
174  $title = $langs->trans("ListProductByPopularity");
175  }
176 
177  $head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'.($type != '' ? '?type='.((int) $type) : '');
178  $head[$h][1] = $langs->trans("ProductsPerPopularity");
179  $head[$h][2] = 'popularity';
180  $h++;
181 
182  print dol_get_fiche_head($head, 'chart', '', -1);
183 }
184 
185 
186 if ($result || !($id > 0)) {
187  print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
188  print '<input type="hidden" name="token" value="'.newToken().'">';
189  if (empty($id) || $notab) {
190  print '<input type="hidden" name="notab" value="1">';
191  }
192 
193  print '<table class="noborder centpercent">';
194  print '<tr class="liste_titre"><td class="liste_titre">'.$langs->trans("Filter").'</td><td></td></tr>';
195 
196  if (!($id > 0) || $notab) {
197  // Type
198  print '<tr class="nooddeven"><td class="titlefield">'.$langs->trans("Type").'</td><td>';
199  $array = array('-1'=>'&nbsp;', '0'=>$langs->trans('Product'), '1'=>$langs->trans('Service'));
200  print $form->selectarray('type', $array, $type, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100');
201  print '</td></tr>';
202 
203  // Product
204  print '<tr class="nooddeven"><td class="titlefield">'.$langs->trans("ProductOrService").'</td><td>';
205  print img_picto('', 'product', 'class="pictofixedwidth"');
206  print $form->select_produits($id, 'id', '', 0, 0, 1, 2, '', ($conf->dol_optimize_smallscreen ? 1 : 0), array(), 0, '1', 0, 'widthcentpercentminusx maxwidth400');
207  print '</td></tr>';
208 
209  // Tag
210  if (isModEnabled('categorie')) {
211  print '<tr class="nooddeven"><td class="titlefield">'.$langs->trans("Categories").'</td><td>';
212  $moreforfilter .= img_picto($langs->trans("Categories"), 'category', 'class="pictofixedwidth"');
213  $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1, 1, 'widthcentpercentminusx maxwidth400');
214  print $moreforfilter;
215  print '</td></tr>';
216  }
217  } else {
218  print '<input type="hidden" name="id" value="'.$id.'">';
219  }
220 
221  // Year
222  print '<tr class="nooddeven"><td class="titlefield">'.$langs->trans("Year").'</td><td>';
223  $arrayyears = array();
224  for ($year = $currentyear - 25; $year < $currentyear; $year++) {
225  $arrayyears[$year] = $year;
226  }
227  if (!in_array($year, $arrayyears)) {
228  $arrayyears[$year] = $year;
229  }
230  if (!in_array($currentyear, $arrayyears)) {
231  $arrayyears[$currentyear] = $currentyear;
232  }
233  arsort($arrayyears);
234  print $form->selectarray('search_year', $arrayyears, $search_year, 1, 0, 0, '', 0, 0, 0, '', 'width75');
235  print '</td></tr>';
236 
237  // thirdparty
238  print '<tr class="nooddeven"><td class="titlefield">'.$langs->trans("ThirdParty").'</td><td>';
239  print img_picto('', 'company', 'class="pictofixedwidth"');
240  print $form->select_company($socid, 'socid', '', 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth400');
241  print '</td></tr>';
242 
243  print '</table>';
244  print '<div class="center"><input type="submit" name="submit" class="button small" value="'.$langs->trans("Refresh").'"></div>';
245  print '</form><br>';
246 
247  print '<br>';
248 
249 
250  $param = '';
251  $param .= (GETPOSTISSET('id') ? '&id='.GETPOST('id', 'int') : '&id='.$object->id).(($type != '' && $type != '-1') ? '&type='.((int) $type) : '').'&search_year='.((int) $search_year).($notab ? '&notab='.$notab : '');
252  if ($socid > 0) {
253  $param .= '&socid='.((int) $socid);
254  }
255 
256  // Choice of stats mode (byunit or bynumber)
257 
258  if (!empty($conf->dol_use_jmobile)) {
259  print "\n".'<div class="fichecenter"><div class="nowrap">'."\n";
260  }
261 
262  if ($mode != 'byunit') {
263  print '<a class="a-mesure-disabled marginleftonly marginrightonly reposition" href="'.$_SERVER["PHP_SELF"].'?mode=byunit'.$param.'">';
264  } else {
265  print '<span class="a-mesure marginleftonly marginrightonly">';
266  }
267  print $langs->trans("StatsByNumberOfUnits");
268  if ($mode != 'byunit') {
269  print '</a>';
270  } else {
271  print '</span>';
272  }
273 
274  if (!empty($conf->dol_use_jmobile)) {
275  print '</div>'."\n".'<div class="nowrap">'."\n";
276  }
277 
278  if ($mode != 'bynumber') {
279  print '<a class="a-mesure-disabled marginleftonly marginrightonly reposition" href="'.$_SERVER["PHP_SELF"].'?mode=bynumber'.$param.'">';
280  } else {
281  print '<span class="a-mesure marginleftonly marginrightonly">';
282  }
283  print $langs->trans("StatsByNumberOfEntities");
284  if ($mode != 'bynumber') {
285  print '</a>';
286  } else {
287  print '</span>';
288  }
289 
290  if (!empty($conf->dol_use_jmobile)) {
291  print '</div>'."\n".'<div class="nowrap">'."\n";
292  }
293 
294  if ($mode != 'byamount') {
295  print '<a class="a-mesure-disabled marginleftonly marginrightonly reposition" href="'.$_SERVER["PHP_SELF"].'?mode=byamount'.$param.'">';
296  } else {
297  print '<span class="a-mesure marginleftonly marginrightonly">';
298  }
299  print $langs->trans("StatsByAmount");
300  if ($mode != 'byamount') {
301  print '</a>';
302  } else {
303  print '</span>';
304  }
305 
306  // End of choices
307  if (!empty($conf->dol_use_jmobile)) {
308  print '</div></div>';
309  } else {
310  print '<br>';
311  }
312  print '<br>';
313 
314  // Generation of graphs
315  $dir = (!empty($conf->product->multidir_temp[$conf->entity]) ? $conf->product->multidir_temp[$conf->entity] : $conf->service->multidir_temp[$conf->entity]);
316  if ($object->id > 0) { // We are on statistics for a dedicated product
317  if (!file_exists($dir.'/'.$object->id)) {
318  if (dol_mkdir($dir.'/'.$object->id) < 0) {
319  $mesg = $langs->trans("ErrorCanNotCreateDir", $dir);
320  $error++;
321  }
322  }
323  }
324 
325  $arrayforlabel = array('byunit' => 'NumberOfUnits', 'bynumber' => 'NumberOf', 'byamount' => 'AmountIn');
326 
327  if (isModEnabled('propal')) {
328  $graphfiles['propal'] = array('modulepart'=>'productstats_proposals',
329  'file' => $object->id.'/propal12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
330  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("Proposals")));
331  }
332 
333  if (isModEnabled('supplier_proposal')) {
334  $langs->load("supplier_proposal");
335  $graphfiles['proposalssuppliers'] = array('modulepart'=>'productstats_proposalssuppliers',
336  'file' => $object->id.'/proposalssuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
337  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("SupplierProposals")));
338  }
339 
340  if (isModEnabled('order')) {
341  $graphfiles['orders'] = array('modulepart'=>'productstats_orders',
342  'file' => $object->id.'/orders12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
343  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("Orders")));
344  }
345 
346  if (isModEnabled('supplier_order')) {
347  $graphfiles['orderssuppliers'] = array('modulepart'=>'productstats_orderssuppliers',
348  'file' => $object->id.'/orderssuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
349  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("SuppliersOrders")));
350  }
351 
352  if (isModEnabled('facture')) {
353  $graphfiles['invoices'] = array('modulepart'=>'productstats_invoices',
354  'file' => $object->id.'/invoices12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
355  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("Invoices")));
356  }
357 
358  if (isModEnabled('supplier_invoice')) {
359  $graphfiles['invoicessuppliers'] = array('modulepart'=>'productstats_invoicessuppliers',
360  'file' => $object->id.'/invoicessuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
361  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("SupplierInvoices")));
362  }
363 
364  if (isModEnabled('contrat')) {
365  $graphfiles['contracts'] = array('modulepart'=>'productstats_contracts',
366  'file' => $object->id.'/contracts12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
367  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("Contracts")));
368  }
369 
370  if (isModEnabled('mrp') && $mode != 'byamount') {
371  $graphfiles['mrp'] = array('modulepart'=>'productstats_mrp',
372  'file' => $object->id.'/mos12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
373  'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode]."Mos"));
374  }
375 
376  $px = new DolGraph();
377 
378  if (!$error && count($graphfiles) > 0) {
379  $mesg = $px->isGraphKo();
380  if (!$mesg) {
381  foreach ($graphfiles as $key => $val) {
382  if (!$graphfiles[$key]['file']) {
383  continue;
384  }
385 
386  $graph_data = array();
387 
388  if (dol_is_file($dir.'/'.$graphfiles[$key]['file'])) {
389  // TODO Load cachefile $graphfiles[$key]['file']
390  } else {
391  $morefilters = '';
392  if ($search_categ > 0) {
393  $categ = new Categorie($db);
394  $categ->fetch($search_categ);
395  $listofprodids = $categ->getObjectsInCateg('product', 1);
396  $morefilters = ' AND d.fk_product IN ('.$db->sanitize((is_array($listofprodids) && count($listofprodids)) ? join(',', $listofprodids) : '0').')';
397  }
398  if ($search_categ == -2) {
399  $morefilters = ' AND NOT EXISTS (SELECT cp.fk_product FROM '.MAIN_DB_PREFIX.'categorie_product as cp WHERE d.fk_product = cp.fk_product)';
400  }
401 
402  if ($key == 'propal') {
403  $graph_data = $object->get_nb_propal($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
404  }
405  if ($key == 'orders') {
406  $graph_data = $object->get_nb_order($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
407  }
408  if ($key == 'invoices') {
409  $graph_data = $object->get_nb_vente($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
410  }
411  if ($key == 'proposalssuppliers') {
412  $graph_data = $object->get_nb_propalsupplier($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
413  }
414  if ($key == 'invoicessuppliers') {
415  $graph_data = $object->get_nb_achat($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
416  }
417  if ($key == 'orderssuppliers') {
418  $graph_data = $object->get_nb_ordersupplier($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
419  }
420  if ($key == 'contracts') {
421  $graph_data = $object->get_nb_contract($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
422  }
423  if ($key == 'mrp') {
424  $graph_data = $object->get_nb_mos($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
425  }
426 
427  // TODO Save cachefile $graphfiles[$key]['file']
428  }
429 
430  if (is_array($graph_data)) {
431  $px->SetData($graph_data);
432  $px->SetYLabel($graphfiles[$key]['label']);
433  $px->SetMaxValue($px->GetCeilMaxValue() < 0 ? 0 : $px->GetCeilMaxValue());
434  $px->SetMinValue($px->GetFloorMinValue() > 0 ? 0 : $px->GetFloorMinValue());
435  $px->setShowLegend(0);
436  $px->SetWidth($WIDTH);
437  $px->SetHeight($HEIGHT);
438  $px->SetHorizTickIncrement(1);
439  $px->SetShading(3);
440  //print 'x '.$key.' '.$graphfiles[$key]['file'];
441 
442  $url = DOL_URL_ROOT.'/viewimage.php?modulepart='.$graphfiles[$key]['modulepart'].'&entity='.((int) $object->entity).'&file='.urlencode($graphfiles[$key]['file']).($notab ? '&notab='.$notab : '');
443  $px->draw($dir."/".$graphfiles[$key]['file'], $url);
444 
445  $graphfiles[$key]['total'] = $px->total();
446  $graphfiles[$key]['output'] = $px->show();
447  } else {
448  dol_print_error($db, 'Error for calculating graph on key='.$key.' - '.$object->error);
449  }
450  }
451 
452  //setEventMessages($langs->trans("ChartGenerated"), null, 'mesgs');
453  }
454  }
455 
456  // Show graphs
457  $i = 0;
458  if (count($graphfiles) > 0) {
459  foreach ($graphfiles as $key => $val) {
460  if (!$graphfiles[$key]['file']) {
461  continue;
462  }
463 
464  if ($graphfiles == 'propal' && empty($user->rights->propal->lire)) {
465  continue;
466  }
467  if ($graphfiles == 'order' && !$user->hasRight('commande', 'lire')) {
468  continue;
469  }
470  if ($graphfiles == 'invoices' && !$user->hasRight('facture', 'lire')) {
471  continue;
472  }
473  if ($graphfiles == 'proposals_suppliers' && empty($user->rights->supplier_proposal->lire)) {
474  continue;
475  }
476  if ($graphfiles == 'invoices_suppliers' && empty($user->rights->fournisseur->facture->lire)) {
477  continue;
478  }
479  if ($graphfiles == 'orders_suppliers' && empty($user->rights->fournisseur->commande->lire)) {
480  continue;
481  }
482  if ($graphfiles == 'mrp' && empty($user->rights->mrp->read)) {
483  continue;
484  }
485 
486 
487  if ($i % 2 == 0) {
488  print "\n".'<div class="fichecenter"><div class="fichehalfleft">'."\n";
489  } else {
490  print "\n".'<div class="fichehalfright">'."\n";
491  }
492 
493  // Date generation
494  if ($graphfiles[$key]['output'] && !$px->isGraphKo()) {
495  if (file_exists($dir."/".$graphfiles[$key]['file']) && filemtime($dir."/".$graphfiles[$key]['file'])) {
496  $dategenerated = $langs->trans("GeneratedOn", dol_print_date(filemtime($dir."/".$graphfiles[$key]['file']), "dayhour"));
497  } else {
498  $dategenerated = $langs->trans("GeneratedOn", dol_print_date(dol_now(), "dayhour"));
499  }
500  } else {
501  $dategenerated = ($mesg ? '<span class="error">'.$mesg.'</span>' : $langs->trans("ChartNotGenerated"));
502  }
503  $linktoregenerate = '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?'.(GETPOSTISSET('id') ? 'id='.GETPOST('id', 'int') : 'id='.$object->id).(((string) $type != '' && $type != '-1') ? '&type='.((int) $type) : '').'&action=recalcul&mode='.urlencode($mode).'&search_year='.((int) $search_year).($search_categ > 0 ? '&search_categ='.((int) $search_categ) : '').'">';
504  $linktoregenerate .= img_picto($langs->trans("ReCalculate").' ('.$dategenerated.')', 'refresh');
505  $linktoregenerate .= '</a>';
506 
507 
508  // Show graph
509  print '<div class="div-table-responsive-no-min">';
510  print '<table class="noborder centpercent">';
511  // Label
512  print '<tr class="liste_titre"><td>';
513  print $graphfiles[$key]['label'];
514  print ' <span class="opacitymedium">('.$graphfiles[$key]['total'].')</span></td>';
515  print '<td align="right">'.$linktoregenerate.'</td>';
516  print '</tr>';
517  // Image
518  print '<tr><td colspan="2" class="nohover" align="center">';
519  print $graphfiles[$key]['output'];
520  print '</td></tr>';
521  print '</table>';
522  print '</div>';
523 
524  if ($i % 2 == 0) {
525  print "\n".'</div>'."\n";
526  } else {
527  print "\n".'</div></div>';
528  print '<div class="clear"><div class="fichecenter"><br></div></div>'."\n";
529  }
530 
531  $i++;
532  }
533  }
534  // div not closed
535  if ($i % 2 == 1) {
536  print "\n".'<div class="fichehalfright">'."\n";
537  print "\n".'</div></div>';
538  print '<div class="clear"><div class="fichecenter"><br></div></div>'."\n";
539  }
540 }
541 
542 if (!($id > 0)) {
543  print dol_get_fiche_end();
544 }
545 
546 // End of page
547 llxFooter();
548 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage categories.
Class to build graphs.
static getDefaultGraphSizeForStats($direction, $defaultsize='')
getDefaultGraphSizeForStats
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:483
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
product_prepare_head($object)
Prepare array with list of tabs.
Definition: product.lib.php:36
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.