dolibarr 21.0.0-alpha
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012 Marcos García <marcosgdf@gmail.com>
6 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
7 * Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
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
31require '../../../main.inc.php';
32require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propalestats.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
34require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
38
41
42$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer';
43
44$hookmanager->initHooks(array('propalstats', 'globalcard'));
45
46$object_status = GETPOST('object_status', 'intcomma');
47$typent_id = GETPOSTINT('typent_id');
48$categ_id = GETPOSTINT('categ_id');
49
50$userid = GETPOSTINT('userid');
51$socid = GETPOSTINT('socid');
52// Security check
53if ($user->socid > 0) {
54 $action = '';
55 $socid = $user->socid;
56}
57
58$parameters = array();
59$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
60if ($reshook < 0) {
61 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
62}
63
64$nowyear = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
65$year = GETPOST('year') > 0 ? GETPOSTINT('year') : $nowyear;
66$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
67$endyear = $year;
68
69// Load translation files required by the page
70$langs->loadLangs(array('orders', 'companies', 'other', 'suppliers', 'supplier_proposal'));
71
72if ($mode == 'customer' && !$user->hasRight('propal', 'lire')) {
74}
75if ($mode == 'supplier' && !$user->hasRight('supplier_proposal', 'lire')) {
77}
78
79
80/*
81 * View
82 */
83
84$form = new Form($db);
85$formpropal = new FormPropal($db);
86$formcompany = new FormCompany($db);
87$formother = new FormOther($db);
88
89$langs->loadLangs(array('propal', 'other', 'companies'));
90
91$picto = null;
92$dir = null;
93$cat_type = null;
94$cat_label = null;
95
96if ($mode == 'customer') {
97 $picto = 'propal';
98 $title = $langs->trans("ProposalsStatistics");
99 $dir = $conf->propal->dir_temp;
100 $cat_type = Categorie::TYPE_CUSTOMER;
101 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Customer"));
102}
103if ($mode == 'supplier') {
104 $picto = 'supplier_proposal';
105 $title = $langs->trans("ProposalsStatisticsSuppliers");
106 $dir = $conf->supplier_proposal->dir_temp;
107 $cat_type = Categorie::TYPE_SUPPLIER;
108 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Supplier"));
109}
110
111llxHeader('', $title);
112
113print load_fiche_titre($title, '', $picto);
114
115
116dol_mkdir($dir);
117
118
119$stats = new PropaleStats($db, $socid, ($userid > 0 ? $userid : 0), $mode, ($typent_id > 0 ? $typent_id : 0), ($categ_id > 0 ? $categ_id : 0));
120if ($object_status != '' && $object_status >= 0) {
121 $stats->where .= ' AND p.fk_statut IN ('.$db->sanitize($object_status).')';
122}
123
124// Build graphic number of object
125$data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
126// $data = array(array('Lib',val1,val2,val3),...)
127
128
129if (!$user->hasRight('societe', 'client', 'voir')) {
130 $filenamenb = $dir.'/proposalsnbinyear-'.$user->id.'-'.$year.'.png';
131 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$user->id.'-'.$year.'.png';
132} else {
133 $filenamenb = $dir.'/proposalsnbinyear-'.$year.'.png';
134 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$year.'.png';
135}
136
137$px1 = new DolGraph();
138$mesg = $px1->isGraphKo();
139if (!$mesg) {
140 $px1->SetData($data);
141 $i = $startyear;
142 $legend = array();
143 while ($i <= $endyear) {
144 $legend[] = $i;
145 $i++;
146 }
147 $px1->SetLegend($legend);
148 $px1->SetMaxValue($px1->GetCeilMaxValue());
149 $px1->SetMinValue(min(0, $px1->GetFloorMinValue()));
150 $px1->SetWidth($WIDTH);
151 $px1->SetHeight($HEIGHT);
152 $px1->SetYLabel($langs->trans("NbOfProposals"));
153 $px1->SetShading(3);
154 $px1->SetHorizTickIncrement(1);
155 $px1->mode = 'depth';
156 $px1->SetTitle($langs->trans("NumberOfProposalsByMonth"));
157
158 $px1->draw($filenamenb, $fileurlnb);
159}
160
161// Build graphic amount of object
162$data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear, 0);
163// $data = array(array('Lib',val1,val2,val3),...)
164
165if (!$user->hasRight('societe', 'client', 'voir')) {
166 $filenameamount = $dir.'/proposalsamountinyear-'.$user->id.'-'.$year.'.png';
167 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$user->id.'-'.$year.'.png';
168} else {
169 $filenameamount = $dir.'/proposalsamountinyear-'.$year.'.png';
170 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$year.'.png';
171}
172
173$px2 = new DolGraph();
174$mesg = $px2->isGraphKo();
175if (!$mesg) {
176 $px2->SetData($data);
177 $i = $startyear;
178 $legend = array();
179 while ($i <= $endyear) {
180 $legend[] = $i;
181 $i++;
182 }
183 $px2->SetLegend($legend);
184 $px2->SetMaxValue($px2->GetCeilMaxValue());
185 $px2->SetMinValue(min(0, $px2->GetFloorMinValue()));
186 $px2->SetWidth($WIDTH);
187 $px2->SetHeight($HEIGHT);
188 $px2->SetYLabel($langs->trans("AmountOfProposals"));
189 $px2->SetShading(3);
190 $px2->SetHorizTickIncrement(1);
191 $px2->mode = 'depth';
192 $px2->SetTitle($langs->trans("AmountOfProposalsByMonthHT"));
193
194 $px2->draw($filenameamount, $fileurlamount);
195}
196
197$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear);
198
199$fileurl_avg = '';
200if (!$user->hasRight('societe', 'client', 'voir')) {
201 $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png';
202 if ($mode == 'customer') {
203 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png';
204 }
205 if ($mode == 'supplier') {
206 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$user->id.'-'.$year.'.png';
207 }
208} else {
209 $filename_avg = $dir.'/ordersaverage-'.$year.'.png';
210 if ($mode == 'customer') {
211 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$year.'.png';
212 }
213 if ($mode == 'supplier') {
214 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$year.'.png';
215 }
216}
217
218$px3 = new DolGraph();
219$mesg = $px3->isGraphKo();
220if (!$mesg) {
221 $px3->SetData($data);
222 $i = $startyear;
223 $legend = array();
224 while ($i <= $endyear) {
225 $legend[] = $i;
226 $i++;
227 }
228 $px3->SetLegend($legend);
229 $px3->SetYLabel($langs->trans("AmountAverage"));
230 $px3->SetMaxValue($px3->GetCeilMaxValue());
231 $px3->SetMinValue($px3->GetFloorMinValue());
232 $px3->SetWidth($WIDTH);
233 $px3->SetHeight($HEIGHT);
234 $px3->SetShading(3);
235 $px3->SetHorizTickIncrement(1);
236 $px3->mode = 'depth';
237 $px3->SetTitle($langs->trans("AmountAverage"));
238
239 $px3->draw($filename_avg, $fileurl_avg);
240}
241
242
243// Show array
244$data = $stats->getAllByYear();
245$arrayyears = array();
246foreach ($data as $val) {
247 if (!empty($val['year'])) {
248 $arrayyears[$val['year']] = $val['year'];
249 }
250}
251if (!count($arrayyears)) {
252 $arrayyears[$nowyear] = $nowyear;
253}
254
255
256$h = 0;
257$head = array();
258$head[$h][0] = DOL_URL_ROOT.'/comm/propal/stats/index.php';
259$head[$h][1] = $langs->trans("ByMonthYear");
260$head[$h][2] = 'byyear';
261$h++;
262
263complete_head_from_modules($conf, $langs, null, $head, $h, 'propal_stats');
264
265print dol_get_fiche_head($head, 'byyear', '', -1);
266
267
268print '<div class="fichecenter"><div class="fichethirdleft">';
269
270
271// Show filter box
272print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
273print '<input type="hidden" name="token" value="'.newToken().'">';
274print '<input type="hidden" name="mode" value="'.$mode.'">';
275
276print '<table class="noborder centpercent">';
277print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
278// Company
279print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
280print img_picto('', 'company', 'class="pictofixedwidth"');
281$filter = '(s.client:IN:1,2,3)';
282print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
283print '</td></tr>';
284// ThirdParty Type
285print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
286$sortparam_typent = (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
287print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
288if ($user->admin) {
289 print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
290}
291print '</td></tr>';
292// Category
293print '<tr><td>'.$cat_label.'</td><td>';
294print img_picto('', 'category', 'class="pictofixedwidth"');
295print $formother->select_categories($cat_type, $categ_id, 'categ_id', 0, 1, 'widthcentpercentminusx maxwidth300');
296print '</td></tr>';
297// User
298print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
299print img_picto('', 'user', 'class="pictofixedwidth"');
300print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
301print '</td></tr>';
302// Status
303print '<tr><td>'.$langs->trans("Status").'</td><td>';
304$formpropal->selectProposalStatus(($object_status != '' ? $object_status : -1), 0, 0, 1, $mode, 'object_status');
305print '</td></tr>';
306// Year
307print '<tr><td>'.$langs->trans("Year").'</td><td>';
308if (!in_array($year, $arrayyears)) {
309 $arrayyears[$year] = $year;
310}
311if (!in_array($nowyear, $arrayyears)) {
312 $arrayyears[$nowyear] = $nowyear;
313}
314arsort($arrayyears);
315print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
316print '</td></tr>';
317print '<tr><td align="center" colspan="2"><input type="submit" name="submit" class="button small" value="'.$langs->trans("Refresh").'"></td></tr>';
318print '</table>';
319print '</form>';
320print '<br><br>';
321
322print '<div class="div-table-responsive-no-min">';
323print '<table class="noborder centpercent">';
324print '<tr class="liste_titre" height="24">';
325print '<td class="center">'.$langs->trans("Year").'</td>';
326print '<td class="right">'.$langs->trans("NbOfProposals").'</td>';
327print '<td class="right">%</td>';
328print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
329print '<td class="right">%</td>';
330print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
331print '<td class="right">%</td>';
332print '</tr>';
333
334$oldyear = 0;
335foreach ($data as $val) {
336 $year = $val['year'];
337 while (!empty($year) && $oldyear > (int) $year + 1) { // If we have empty year
338 $oldyear--;
339
340 print '<tr class="oddeven" height="24">';
341 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$oldyear.'</a></td>';
342 print '<td class="right">0</td>';
343 print '<td class="right"></td>';
344 print '<td class="right">0</td>';
345 print '<td class="right"></td>';
346 print '<td class="right">0</td>';
347 print '<td class="right"></td>';
348 print '</tr>';
349 }
350 print '<tr class="oddeven" height="24">';
351 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
352 print '<td class="right">'.$val['nb'].'</td>';
353 print '<td class="right opacitylow" style="'.((!isset($val['nb_diff']) || $val['nb_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['nb_diff']) ? round($val['nb_diff']) : "0").'%</td>';
354 print '<td class="right">'.price(price2num($val['total'], 'MT'), 1).'</td>';
355 print '<td class="right opacitylow" style="'.((!isset($val['total_diff']) || $val['total_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%</td>';
356 print '<td class="right">'.price(price2num($val['avg'], 'MT'), 1).'</td>';
357 print '<td class="right opacitylow" style="'.((!isset($val['avg_diff']) || $val['avg_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%</td>';
358 print '</tr>';
359 $oldyear = $year;
360}
361
362print '</table>';
363print '</div>';
364
365print '</div><div class="fichetwothirdright">';
366
367
368// Show graphs
369print '<table class="border centpercent"><tr class="pair nohover"><td align="center">';
370if ($mesg) {
371 print $mesg;
372} else {
373 print $px1->show();
374 print "<br>\n";
375 print $px2->show();
376 print "<br>\n";
377 print $px3->show();
378}
379print '</td></tr></table>';
380
381
382print '</div></div>';
383print '<div class="clearboth"></div>';
384
385
386print dol_get_fiche_end();
387
388// End of page
389llxFooter();
390$db->close();
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:70
Class to build graphs.
static getDefaultGraphSizeForStats($direction, $defaultsize='')
getDefaultGraphSizeForStats
Class to build HTML component for third parties management Only common components are here.
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 generation of HTML components for proposal management.
Class to manage proposals statistics.
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.