dolibarr 18.0.6
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
30require '../../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
35require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
36require_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');
57if (!empty($user->socid)) {
58 $socid = $user->socid;
59}
60if ($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'];
73if (empty($search_year)) {
74 $search_year = $currentyear;
75}
76$moreforfilter = "";
77
78$object = new Product($db);
79if ($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
100if (!($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
147if ($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&type='.$object->type.'">'.$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}
160if ((!($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
186if ($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
542if (!($id > 0)) {
543 print dol_get_fiche_end();
544}
545
546// End of page
547llxFooter();
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.
dol_is_file($pathoffile)
Return if path is a file.
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.
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.