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