dolibarr 21.0.0-beta
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 * Copyright (C) 2024 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';
33require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propalestats.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.formpropal.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
39
50
51$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer';
52
53$hookmanager->initHooks(array('propalstats', 'globalcard'));
54
55$object_status = GETPOST('object_status', 'intcomma');
56$typent_id = GETPOSTINT('typent_id');
57$categ_id = GETPOSTINT('categ_id');
58
59$userid = GETPOSTINT('userid');
60$socid = GETPOSTINT('socid');
61// Security check
62if ($user->socid > 0) {
63 $action = '';
64 $socid = $user->socid;
65}
66
67$parameters = array();
68$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
69if ($reshook < 0) {
70 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
71}
72
73$nowyear = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
74$year = GETPOST('year') > 0 ? GETPOSTINT('year') : $nowyear;
75$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
76$endyear = $year;
77
78// Load translation files required by the page
79$langs->loadLangs(array('orders', 'companies', 'other', 'suppliers', 'supplier_proposal'));
80
81if ($mode == 'customer' && !$user->hasRight('propal', 'lire')) {
83}
84if ($mode == 'supplier' && !$user->hasRight('supplier_proposal', 'lire')) {
86}
87
88
89/*
90 * View
91 */
92
93$form = new Form($db);
94$formpropal = new FormPropal($db);
95$formcompany = new FormCompany($db);
96$formother = new FormOther($db);
97
98$langs->loadLangs(array('propal', 'other', 'companies'));
99
100$picto = 'propal';
101$title = $langs->trans("ProposalsStatistics");
102$dir = $conf->propal->dir_temp;
103$cat_type = Categorie::TYPE_CUSTOMER;
104$cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Customer"));
105
106if ($mode == 'supplier') {
107 $picto = 'supplier_proposal';
108 $title = $langs->trans("ProposalsStatisticsSuppliers");
109 $dir = $conf->supplier_proposal->dir_temp;
110 $cat_type = Categorie::TYPE_SUPPLIER;
111 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Supplier"));
112}
113
114llxHeader('', $title);
115
116print load_fiche_titre($title, '', $picto);
117
118
119dol_mkdir($dir);
120
121
122$stats = new PropaleStats($db, $socid, ($userid > 0 ? $userid : 0), $mode, ($typent_id > 0 ? $typent_id : 0), ($categ_id > 0 ? $categ_id : 0));
123if ($object_status != '' && $object_status >= 0) {
124 $stats->where .= ' AND p.fk_statut IN ('.$db->sanitize($object_status).')';
125}
126
127// Build graphic number of object
128$data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
129// $data = array(array('Lib',val1,val2,val3),...)
130
131
132if (!$user->hasRight('societe', 'client', 'voir')) {
133 $filenamenb = $dir.'/proposalsnbinyear-'.$user->id.'-'.$year.'.png';
134 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$user->id.'-'.$year.'.png';
135} else {
136 $filenamenb = $dir.'/proposalsnbinyear-'.$year.'.png';
137 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$year.'.png';
138}
139
140$px1 = new DolGraph();
141$mesg = $px1->isGraphKo();
142if (!$mesg) {
143 $px1->SetData($data);
144 $i = $startyear;
145 $legend = array();
146 while ($i <= $endyear) {
147 $legend[] = $i;
148 $i++;
149 }
150 $px1->SetLegend($legend);
151 $px1->SetMaxValue($px1->GetCeilMaxValue());
152 $px1->SetMinValue(min(0, $px1->GetFloorMinValue()));
153 $px1->SetWidth($WIDTH);
154 $px1->SetHeight($HEIGHT);
155 $px1->SetYLabel($langs->trans("NbOfProposals"));
156 $px1->SetShading(3);
157 $px1->SetHorizTickIncrement(1);
158 $px1->mode = 'depth';
159 $px1->SetTitle($langs->trans("NumberOfProposalsByMonth"));
160
161 $px1->draw($filenamenb, $fileurlnb);
162}
163
164// Build graphic amount of object
165$data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear, 0);
166// $data = array(array('Lib',val1,val2,val3),...)
167
168if (!$user->hasRight('societe', 'client', 'voir')) {
169 $filenameamount = $dir.'/proposalsamountinyear-'.$user->id.'-'.$year.'.png';
170 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$user->id.'-'.$year.'.png';
171} else {
172 $filenameamount = $dir.'/proposalsamountinyear-'.$year.'.png';
173 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$year.'.png';
174}
175
176$px2 = new DolGraph();
177$mesg = $px2->isGraphKo();
178if (!$mesg) {
179 $px2->SetData($data);
180 $i = $startyear;
181 $legend = array();
182 while ($i <= $endyear) {
183 $legend[] = $i;
184 $i++;
185 }
186 $px2->SetLegend($legend);
187 $px2->SetMaxValue($px2->GetCeilMaxValue());
188 $px2->SetMinValue(min(0, $px2->GetFloorMinValue()));
189 $px2->SetWidth($WIDTH);
190 $px2->SetHeight($HEIGHT);
191 $px2->SetYLabel($langs->trans("AmountOfProposals"));
192 $px2->SetShading(3);
193 $px2->SetHorizTickIncrement(1);
194 $px2->mode = 'depth';
195 $px2->SetTitle($langs->trans("AmountOfProposalsByMonthHT"));
196
197 $px2->draw($filenameamount, $fileurlamount);
198}
199
200$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear);
201
202$fileurl_avg = '';
203if (!$user->hasRight('societe', 'client', 'voir')) {
204 $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png';
205 if ($mode == 'customer') {
206 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png';
207 }
208 if ($mode == 'supplier') {
209 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$user->id.'-'.$year.'.png';
210 }
211} else {
212 $filename_avg = $dir.'/ordersaverage-'.$year.'.png';
213 if ($mode == 'customer') {
214 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$year.'.png';
215 }
216 if ($mode == 'supplier') {
217 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$year.'.png';
218 }
219}
220
221$px3 = new DolGraph();
222$mesg = $px3->isGraphKo();
223if (!$mesg) {
224 $px3->SetData($data);
225 $i = $startyear;
226 $legend = array();
227 while ($i <= $endyear) {
228 $legend[] = $i;
229 $i++;
230 }
231 $px3->SetLegend($legend);
232 $px3->SetYLabel($langs->trans("AmountAverage"));
233 $px3->SetMaxValue($px3->GetCeilMaxValue());
234 $px3->SetMinValue($px3->GetFloorMinValue());
235 $px3->SetWidth($WIDTH);
236 $px3->SetHeight($HEIGHT);
237 $px3->SetShading(3);
238 $px3->SetHorizTickIncrement(1);
239 $px3->mode = 'depth';
240 $px3->SetTitle($langs->trans("AmountAverage"));
241
242 $px3->draw($filename_avg, $fileurl_avg);
243}
244
245
246// Show array
247$data = $stats->getAllByYear();
248$arrayyears = array();
249foreach ($data as $val) {
250 if (!empty($val['year'])) {
251 $arrayyears[$val['year']] = $val['year'];
252 }
253}
254if (!count($arrayyears)) {
255 $arrayyears[$nowyear] = $nowyear;
256}
257
258
259$h = 0;
260$head = array();
261$head[$h][0] = DOL_URL_ROOT.'/comm/propal/stats/index.php';
262$head[$h][1] = $langs->trans("ByMonthYear");
263$head[$h][2] = 'byyear';
264$h++;
265
266complete_head_from_modules($conf, $langs, null, $head, $h, 'propal_stats');
267
268print dol_get_fiche_head($head, 'byyear', '', -1);
269
270
271print '<div class="fichecenter"><div class="fichethirdleft">';
272
273
274// Show filter box
275print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
276print '<input type="hidden" name="token" value="'.newToken().'">';
277print '<input type="hidden" name="mode" value="'.$mode.'">';
278
279print '<table class="noborder centpercent">';
280print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
281// Company
282print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
283print img_picto('', 'company', 'class="pictofixedwidth"');
284$filter = '(s.client:IN:1,2,3)';
285print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
286print '</td></tr>';
287// ThirdParty Type
288print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
289$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.
290print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
291if ($user->admin) {
292 print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
293}
294print '</td></tr>';
295// Category
296print '<tr><td>'.$cat_label.'</td><td>';
297print img_picto('', 'category', 'class="pictofixedwidth"');
298print $formother->select_categories($cat_type, $categ_id, 'categ_id', 0, 1, 'widthcentpercentminusx maxwidth300');
299print '</td></tr>';
300// User
301print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
302print img_picto('', 'user', 'class="pictofixedwidth"');
303print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
304print '</td></tr>';
305// Status
306print '<tr><td>'.$langs->trans("Status").'</td><td>';
307$formpropal->selectProposalStatus(($object_status != '' ? $object_status : -1), 0, 0, 1, $mode, 'object_status');
308print '</td></tr>';
309// Year
310print '<tr><td>'.$langs->trans("Year").'</td><td>';
311if (!in_array($year, $arrayyears)) {
312 $arrayyears[$year] = $year;
313}
314if (!in_array($nowyear, $arrayyears)) {
315 $arrayyears[$nowyear] = $nowyear;
316}
317arsort($arrayyears);
318print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
319print '</td></tr>';
320print '<tr><td align="center" colspan="2"><input type="submit" name="submit" class="button small" value="'.$langs->trans("Refresh").'"></td></tr>';
321print '</table>';
322print '</form>';
323print '<br><br>';
324
325print '<div class="div-table-responsive-no-min">';
326print '<table class="noborder centpercent">';
327print '<tr class="liste_titre" height="24">';
328print '<td class="center">'.$langs->trans("Year").'</td>';
329print '<td class="right">'.$langs->trans("NbOfProposals").'</td>';
330print '<td class="right">%</td>';
331print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
332print '<td class="right">%</td>';
333print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
334print '<td class="right">%</td>';
335print '</tr>';
336
337$oldyear = 0;
338foreach ($data as $val) {
339 $year = $val['year'];
340 while (!empty($year) && $oldyear > (int) $year + 1) { // If we have empty year
341 $oldyear--;
342
343 print '<tr class="oddeven" height="24">';
344 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>';
345 print '<td class="right">0</td>';
346 print '<td class="right"></td>';
347 print '<td class="right">0</td>';
348 print '<td class="right"></td>';
349 print '<td class="right">0</td>';
350 print '<td class="right"></td>';
351 print '</tr>';
352 }
353 print '<tr class="oddeven" height="24">';
354 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
355 print '<td class="right">'.$val['nb'].'</td>';
356 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>';
357 print '<td class="right">'.price(price2num($val['total'], 'MT'), 1).'</td>';
358 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>';
359 print '<td class="right">'.price(price2num($val['avg'], 'MT'), 1).'</td>';
360 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>';
361 print '</tr>';
362 $oldyear = $year;
363}
364
365print '</table>';
366print '</div>';
367
368print '</div><div class="fichetwothirdright">';
369
370
371// Show graphs
372print '<table class="border centpercent"><tr class="pair nohover"><td align="center">';
373if ($mesg) {
374 print $mesg;
375} else {
376 print $px1->show();
377 print "<br>\n";
378 print $px2->show();
379 print "<br>\n";
380 print $px3->show();
381}
382print '</td></tr></table>';
383
384
385print '</div></div>';
386print '<div class="clearboth"></div>';
387
388
389print dol_get_fiche_end();
390
391// End of page
392llxFooter();
393$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:71
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)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.