dolibarr  17.0.4
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" colspan="2">'.$langs->trans("Filter").'</td></tr>';
195 
196  if (!($id > 0) || $notab) {
197  // Type
198  print '<tr><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><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><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><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><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  if (!empty($conf->dol_use_jmobile)) {
258  print "\n".'<div class="fichecenter"><div class="nowrap">'."\n";
259  }
260 
261  if ($mode == 'bynumber') {
262  print '<a class="a-mesure-disabled marginleftonly marginrightonly reposition" href="'.$_SERVER["PHP_SELF"].'?mode=byunit'.$param.'">';
263  } else {
264  print '<span class="a-mesure marginleftonly marginrightonly">';
265  }
266  print $langs->trans("StatsByNumberOfUnits");
267  if ($mode == 'bynumber') {
268  print '</a>';
269  } else {
270  print '</span>';
271  }
272 
273  if (!empty($conf->dol_use_jmobile)) {
274  print '</div>'."\n".'<div class="nowrap">'."\n";
275  }
276 
277  if ($mode == 'byunit') {
278  print '<a class="a-mesure-disabled marginleftonly marginrightonly reposition" href="'.$_SERVER["PHP_SELF"].'?mode=bynumber'.$param.'">';
279  } else {
280  print '<span class="a-mesure marginleftonly marginrightonly">';
281  }
282  print $langs->trans("StatsByNumberOfEntities");
283  if ($mode == 'byunit') {
284  print '</a>';
285  } else {
286  print '</span>';
287  }
288 
289  if (!empty($conf->dol_use_jmobile)) {
290  print '</div></div>';
291  } else {
292  print '<br>';
293  }
294  print '<br>';
295 
296  // Generation of graphs
297  $dir = (!empty($conf->product->multidir_temp[$conf->entity]) ? $conf->product->multidir_temp[$conf->entity] : $conf->service->multidir_temp[$conf->entity]);
298  if ($object->id > 0) { // We are on statistics for a dedicated product
299  if (!file_exists($dir.'/'.$object->id)) {
300  if (dol_mkdir($dir.'/'.$object->id) < 0) {
301  $mesg = $langs->trans("ErrorCanNotCreateDir", $dir);
302  $error++;
303  }
304  }
305  }
306 
307  if (isModEnabled('propal')) {
308  $graphfiles['propal'] = array('modulepart'=>'productstats_proposals',
309  'file' => $object->id.'/propal12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
310  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsProposals") : $langs->transnoentitiesnoconv("NumberOfProposals")));
311  }
312 
313  if (isModEnabled('supplier_proposal')) {
314  $graphfiles['proposalssuppliers'] = array('modulepart'=>'productstats_proposalssuppliers',
315  'file' => $object->id.'/proposalssuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
316  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsSupplierProposals") : $langs->transnoentitiesnoconv("NumberOfSupplierProposals")));
317  }
318 
319  if (isModEnabled('order')) {
320  $graphfiles['orders'] = array('modulepart'=>'productstats_orders',
321  'file' => $object->id.'/orders12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
322  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsCustomerOrders") : $langs->transnoentitiesnoconv("NumberOfCustomerOrders")));
323  }
324 
325  if (isModEnabled('supplier_order')) {
326  $graphfiles['orderssuppliers'] = array('modulepart'=>'productstats_orderssuppliers',
327  'file' => $object->id.'/orderssuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
328  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsSupplierOrders") : $langs->transnoentitiesnoconv("NumberOfSupplierOrders")));
329  }
330 
331  if (isModEnabled('facture')) {
332  $graphfiles['invoices'] = array('modulepart'=>'productstats_invoices',
333  'file' => $object->id.'/invoices12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
334  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsCustomerInvoices") : $langs->transnoentitiesnoconv("NumberOfCustomerInvoices")));
335  }
336 
337  if (isModEnabled('supplier_invoice')) {
338  $graphfiles['invoicessuppliers'] = array('modulepart'=>'productstats_invoicessuppliers',
339  'file' => $object->id.'/invoicessuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
340  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsSupplierInvoices") : $langs->transnoentitiesnoconv("NumberOfSupplierInvoices")));
341  }
342 
343  if (isModEnabled('contrat')) {
344  $graphfiles['contracts'] = array('modulepart'=>'productstats_contracts',
345  'file' => $object->id.'/contracts12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
346  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsContracts") : $langs->transnoentitiesnoconv("NumberOfContracts")));
347  }
348 
349  if (isModEnabled('mrp')) {
350  $graphfiles['mrp'] = array('modulepart'=>'productstats_mrp',
351  'file' => $object->id.'/mos12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
352  'label' => ($mode == 'byunit' ? $langs->transnoentitiesnoconv("NumberOfUnitsMos") : $langs->transnoentitiesnoconv("NumberOfMos")));
353  }
354 
355  $px = new DolGraph();
356 
357  if (!$error && count($graphfiles) > 0) {
358  $mesg = $px->isGraphKo();
359  if (!$mesg) {
360  foreach ($graphfiles as $key => $val) {
361  if (!$graphfiles[$key]['file']) {
362  continue;
363  }
364 
365  $graph_data = array();
366 
367  if (dol_is_file($dir.'/'.$graphfiles[$key]['file'])) {
368  // TODO Load cachefile $graphfiles[$key]['file']
369  } else {
370  $morefilters = '';
371  if ($search_categ > 0) {
372  $categ = new Categorie($db);
373  $categ->fetch($search_categ);
374  $listofprodids = $categ->getObjectsInCateg('product', 1);
375  $morefilters = ' AND d.fk_product IN ('.$db->sanitize((is_array($listofprodids) && count($listofprodids)) ? join(',', $listofprodids) : '0').')';
376  }
377  if ($search_categ == -2) {
378  $morefilters = ' AND NOT EXISTS (SELECT cp.fk_product FROM '.MAIN_DB_PREFIX.'categorie_product as cp WHERE d.fk_product = cp.fk_product)';
379  }
380 
381  if ($key == 'propal') {
382  $graph_data = $object->get_nb_propal($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
383  }
384  if ($key == 'orders') {
385  $graph_data = $object->get_nb_order($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
386  }
387  if ($key == 'invoices') {
388  $graph_data = $object->get_nb_vente($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
389  }
390  if ($key == 'proposalssuppliers') {
391  $graph_data = $object->get_nb_propalsupplier($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
392  }
393  if ($key == 'invoicessuppliers') {
394  $graph_data = $object->get_nb_achat($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
395  }
396  if ($key == 'orderssuppliers') {
397  $graph_data = $object->get_nb_ordersupplier($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
398  }
399  if ($key == 'contracts') {
400  $graph_data = $object->get_nb_contract($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
401  }
402  if ($key == 'mrp') {
403  $graph_data = $object->get_nb_mos($socid, $mode, ((string) $type != '' ? $type : -1), $search_year, $morefilters);
404  }
405 
406  // TODO Save cachefile $graphfiles[$key]['file']
407  }
408 
409  if (is_array($graph_data)) {
410  $px->SetData($graph_data);
411  $px->SetYLabel($graphfiles[$key]['label']);
412  $px->SetMaxValue($px->GetCeilMaxValue() < 0 ? 0 : $px->GetCeilMaxValue());
413  $px->SetMinValue($px->GetFloorMinValue() > 0 ? 0 : $px->GetFloorMinValue());
414  $px->setShowLegend(0);
415  $px->SetWidth($WIDTH);
416  $px->SetHeight($HEIGHT);
417  $px->SetHorizTickIncrement(1);
418  $px->SetShading(3);
419  //print 'x '.$key.' '.$graphfiles[$key]['file'];
420 
421  $url = DOL_URL_ROOT.'/viewimage.php?modulepart='.$graphfiles[$key]['modulepart'].'&entity='.((int) $object->entity).'&file='.urlencode($graphfiles[$key]['file']).($notab ? '&notab='.$notab : '');
422  $px->draw($dir."/".$graphfiles[$key]['file'], $url);
423 
424  $graphfiles[$key]['total'] = $px->total();
425  $graphfiles[$key]['output'] = $px->show();
426  } else {
427  dol_print_error($db, 'Error for calculating graph on key='.$key.' - '.$object->error);
428  }
429  }
430 
431  //setEventMessages($langs->trans("ChartGenerated"), null, 'mesgs');
432  }
433  }
434 
435  // Show graphs
436  $i = 0;
437  if (count($graphfiles) > 0) {
438  foreach ($graphfiles as $key => $val) {
439  if (!$graphfiles[$key]['file']) {
440  continue;
441  }
442 
443  if ($graphfiles == 'propal' && empty($user->rights->propal->lire)) {
444  continue;
445  }
446  if ($graphfiles == 'order' && empty($user->rights->commande->lire)) {
447  continue;
448  }
449  if ($graphfiles == 'invoices' && empty($user->rights->facture->lire)) {
450  continue;
451  }
452  if ($graphfiles == 'proposals_suppliers' && empty($user->rights->supplier_proposal->lire)) {
453  continue;
454  }
455  if ($graphfiles == 'invoices_suppliers' && empty($user->rights->fournisseur->facture->lire)) {
456  continue;
457  }
458  if ($graphfiles == 'orders_suppliers' && empty($user->rights->fournisseur->commande->lire)) {
459  continue;
460  }
461  if ($graphfiles == 'mrp' && empty($user->rights->mrp->read)) {
462  continue;
463  }
464 
465 
466  if ($i % 2 == 0) {
467  print "\n".'<div class="fichecenter"><div class="fichehalfleft">'."\n";
468  } else {
469  print "\n".'<div class="fichehalfright">'."\n";
470  }
471 
472  // Date generation
473  if ($graphfiles[$key]['output'] && !$px->isGraphKo()) {
474  if (file_exists($dir."/".$graphfiles[$key]['file']) && filemtime($dir."/".$graphfiles[$key]['file'])) {
475  $dategenerated = $langs->trans("GeneratedOn", dol_print_date(filemtime($dir."/".$graphfiles[$key]['file']), "dayhour"));
476  } else {
477  $dategenerated = $langs->trans("GeneratedOn", dol_print_date(dol_now(), "dayhour"));
478  }
479  } else {
480  $dategenerated = ($mesg ? '<span class="error">'.$mesg.'</span>' : $langs->trans("ChartNotGenerated"));
481  }
482  $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) : '').'">';
483  $linktoregenerate .= img_picto($langs->trans("ReCalculate").' ('.$dategenerated.')', 'refresh');
484  $linktoregenerate .= '</a>';
485 
486 
487  // Show graph
488  print '<div class="div-table-responsive-no-min">';
489  print '<table class="noborder centpercent">';
490  // Label
491  print '<tr class="liste_titre"><td>';
492  print $graphfiles[$key]['label'];
493  print ' <span class="opacitymedium">('.$graphfiles[$key]['total'].')</span></td>';
494  print '<td align="right">'.$linktoregenerate.'</td>';
495  print '</tr>';
496  // Image
497  print '<tr class="impair"><td colspan="2" class="nohover" align="center">';
498  print $graphfiles[$key]['output'];
499  print '</td></tr>';
500  print '</table>';
501  print '</div>';
502 
503  if ($i % 2 == 0) {
504  print "\n".'</div>'."\n";
505  } else {
506  print "\n".'</div></div>';
507  print '<div class="clear"><div class="fichecenter"><br></div></div>'."\n";
508  }
509 
510  $i++;
511  }
512  }
513  // div not closed
514  if ($i % 2 == 1) {
515  print "\n".'<div class="fichehalfright">'."\n";
516  print "\n".'</div></div>';
517  print '<div class="clear"><div class="fichecenter"><br></div></div>'."\n";
518  }
519 }
520 
521 if (!($id > 0)) {
522  print dol_get_fiche_end();
523 }
524 
525 // End of page
526 llxFooter();
527 $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:481
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='')
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:35
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.