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